windows - Hvorfor forbruger XCOPY/W og REPLACE/W alle omdirigerede tekstdata for deres en tegnprompt?

Indlæg af Hanne Mølgaard Plasc

Problem



Når du har en tekstfil test.txt indeholdende denne 1 :



test
data



Følgende kode returnerer indholdet af tekstfilen med det første tegn fjernet:


< "test.txt" (
    > nul pause
    findstr "^"
)


Det samme sker, når du bruger et rør:


type "test.txt" | (
    > nul pause
    findstr "^"
)


Fordi kommandoen pause tager nøjagtigt et tegn.


Men når du erstatter kommandoen pause ved hjælp af en af ​​følgende kommandoer, er outputet tomt, selvom - som pause - de spørger (/W) kun for et enkelt tegn:



  • 2> nul xcopy /W ? .

  • replace /W /U ? .



Hvorfor er det her, hvad sker der?

Er xcopy /W og replace /W forbrugende alle omdirigerede/pipede tekstdata, selv flere linjer, selvom de kun viser det første tegn, de modtager? Er de rundt med filpekeren?

Er der en måde at forhindre, at disse kommandoer absorberer mere end en enkelt karakter?





1 ... Med den sidste linje afsluttet af en linjeskift for at findstr ikke skal hænge på ubestemt tid - se denne tråd: Hvad er de ukendte funktioner og begrænsninger i Windows FINDSTR kommandoen ?, sektion »FINDSTR hænger på XP og Windows 7, hvis omdirigeret input ikke slutter med <LF>« .

Bedste reference


Opførelsen varierer faktisk lidt mellem omdirigering mod et rør.


Redirection



Det ser ud til, at XCOPY og REPLACE blot flytter stdin-filpekeren til End-Of-File (EOF).


Hvis du bruger FIND /V "" i stedet for FINDSTR "^", får du hele filen som output, fordi FIND nulstiller filpegeren til begyndelsen af ​​filen ved opstart. Så stdin-strømmen er stadig gyldig efter XCOPY-kørslen, men filpekeren er ved EOF.


XCOPY skal flytte filmarkøren uden at læse alle dataene, fordi når jeg bruger big.txt indeholdende 0,5 GBytes, er det stadig 'øjeblikkeligt'. Der ville være en betydelig forsinkelse, hvis XCOPY skulle læse hele filen, før den fortsatte.


Rør



Jeg forstår ikke fuldt ud konsekvenserne af dette, men jeg tror, ​​at standardrøret er blokeret. XCOPY og REPLACE læser op til 1 fuld blok, før de fortsætter, og resten af ​​rørdataene til FINDSTR læses.


Jeg pipede i en 127 linjepil, der indeholdt 4191 bytes, og FINDSTR output 97 bytes over 3 linjer. Så i dette tilfælde synes XCOPY at læse 4094 bytes.


Jeg pipede derefter i en 5000 byte fil uden nye linjer og FINDSTR output 908 bytes, hvilket betyder at XCOPY ser ud til at læse 4092 bytes.


Så rørblokbufferen skal være et sted i nærheden af ​​4 kbytes. Min gætte er XCOPY flytter blot filpegeren til slutningen af ​​den aktuelle buffer uden at læse alle dataene, men jeg ved ikke, hvordan man skal teste det.


Som det ville forventes, ændrer FIND for FINDSTR ikke resultatet ved brug af rør - der er ingen måde at nulstille filpekeren tilbage til begyndelsen af ​​rørdataene, efter at den allerede er blevet læst.





Jeg kan ikke forestille mig, at der er nogen måde at ændre adfærd hos XCOPY eller REPLACE ... det er hvad det er.


Hvorfor XCOPY og REPLACE opfører sig som de gør? Jeg har ikke en anelse. Microsoft 'batch' -verdenen er så idiosynkratisk, at jeg gav op spørger mig for længe siden.