Поведение на самом деле немного меняется между перенаправлением и конвейером.
Перенаправление
Похоже, что 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 настолько своеобразен, что я давно перестал спрашивать, почему.