Почему XCOPY / W и REPLACE / W используют все перенаправленные текстовые данные для односимвольной подсказки? - PullRequest
0 голосов
/ 09 мая 2018

При наличии текстового файла test.txt, содержащего это 1 :

test
data

Следующий код возвращает содержимое текстового файла с удаленным первым символом:

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

То же самое происходит при использовании трубы:

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

Поскольку команда pause принимает ровно один символ.

Однако при замене команды pause любой из следующих команд вывод будет пустым, хотя - как и pause - они запрашивают (/W) только для одного символа:

  • 2> nul xcopy /W ? .
  • replace /W /U ? .

Почему это, что здесь происходит?
xcopy /W и replace /W используют все перенаправленные / переданные по трубопроводу текстовые данные, даже несколько строк, хотя они отображают только первый символ, который они получают? Они возятся с указателем файла?
Есть ли способ предотвратить поглощение этими командами более одного символа?


1… С последней строкой, оканчивающейся переводом строки, чтобы findstr не зависал бесконечно - см. Эту ветку: Каковы недокументированные функции и ограничения команды Windows FINDSTR? , раздел »FINDSTR зависает на XP и Windows 7, если перенаправленный ввод не заканчивается на <LF>« .

1 Ответ

0 голосов
/ 09 мая 2018

Поведение на самом деле немного меняется между перенаправлением и конвейером.

Перенаправление

Похоже, что XCOPY и REPLACE просто перемещают указатель файла stdin в конец файла (EOF).

Если вы используете FIND /V "" вместо FINDSTR "^", тогда вы получите весь файл как выходной, потому что FIND сбрасывает указатель файла на начало файла при запуске. Таким образом, поток stdin по-прежнему действителен после запуска XCOPY, но указатель файла имеет значение EOF.

XCOPY должен перемещать указатель файла, фактически не считывая все данные, потому что когда я использую big.txt, содержащий 0,5 ГБ, он все еще «мгновенный». Если XCOPY должен будет прочитать весь файл, прежде чем он продолжит работу, будет существенная задержка.

Труба

Я не до конца понимаю последствия этого, но я считаю, что стандартный канал является блочной буферизацией. XCOPY и REPLACE читают до 1 полного блока перед тем, как продолжить, оставляя оставшуюся часть переданных данных для FINDSTR для чтения.

Я передал файл из 127 строк, содержащий 4191 байт, и FINDSTR вывел 97 байтов за 3 строки. Таким образом, в этом случае XCOPY выглядит как 4094 байта.

Затем я передал файл размером 5000 байт без каких-либо новых строк, и FINDSTR вывел 908 байт, что означает, что XCOPY, кажется, читает 4092 байта.

Таким образом, буфер конвейерного блока должен быть где-то около 4 килобайт. Я предполагаю, что XCOPY просто перемещает указатель файла в конец текущего буфера, не читая все данные, но я не знаю, как это проверить.

Как и следовало ожидать, замена FIND для FINDSTR не изменяет результат при использовании конвейеров - нет способа вернуть указатель файла обратно в начало переданных данных после того, как они уже прочитаны.


Я не могу себе представить, что есть способ изменить поведение XCOPY или REPLACE ... это то, что есть.

А почему XCOPY и REPLACE ведут себя так же, как они? ... Понятия не имею. «Пакетный» мир Microsoft настолько своеобразен, что я давно перестал спрашивать, почему.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...