为什么 XCOPY /W 和 REPLACE /W 为它们的单字符提示消耗所有重定向的文本数据?
Why do XCOPY /W and REPLACE /W consume all redirected text data for their one-character prompt?
当文本文件 test.txt
包含此内容时1:
test
data
下面的代码returns去掉第一个字符的文本文件的内容:
< "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
是否消耗所有 redirected/piped 文本数据,甚至是多行,尽管它们只显示接收到的第一个字符?他们在乱弄文件指针吗?
有没有办法防止这些命令吸收多个字符?
1 ... 最后一行以换行符终止,以便 findstr
不会无限期地挂起 – 请参阅此线程:What are the undocumented features and limitations of the Windows FINDSTR command?,第 »FINDSTR 在 XP 和 Windows 7 上挂起,如果重定向的输入不以 <LF>
«.
结尾
重定向与管道之间的行为实际上有所不同。
重定向
似乎 XCOPY 和 REPLACE 只是将标准输入文件指针移动到文件结尾 (EOF)。
如果您使用 FIND /V ""
而不是 FINDSTR "^"
,那么您将得到整个文件作为输出,因为 FIND 在启动时将文件指针重置为文件的开头。所以XCOPY运行后stdin流仍然有效,但是文件指针在EOF。
XCOPY 必须在没有实际读取所有数据的情况下移动文件指针,因为当我使用包含 0.5 GBytes 的 big.txt 时,它仍然是“瞬时的”。如果 XCOPY 在继续之前必须读取所有文件,将会有明显的延迟。
管道
我不完全理解这意味着什么,但我相信标准管道是块缓冲的。 XCOPY 和 REPLACE 在继续之前最多读取 1 个完整块,将剩余的管道数据留给 FINDSTR 读取。
我输入了一个包含 4191 个字节的 127 行文件,FINDSTR 在 3 行中输出了 97 个字节。所以在这种情况下,XCOPY 似乎读取了 4094 个字节。
然后我在没有任何新行的情况下输入了一个 5000 字节的文件,FINDSTR 输出了 908 字节,这意味着 XCOPY 似乎读取了 4092 字节。
所以管道块缓冲区必须在 4 kbytes 附近的某个地方。我的猜测是 XCOPY 只是将文件指针移动到当前缓冲区的末尾而不读取所有数据,但我不知道如何测试它。
正如预期的那样,用 FIND 代替 FINDSTR 不会改变使用管道时的结果 - 在读取数据后,无法将文件指针重置回管道数据的开头。
我无法想象有什么方法可以修改 XCOPY 或 REPLACE 的行为...就是这样。
至于为什么 XCOPY 和 REPLACE 的行为方式是这样的?......我没有任何线索。微软的“批处理”世界是如此奇特,我早就放弃了问为什么。
当文本文件 test.txt
包含此内容时1:
test data
下面的代码returns去掉第一个字符的文本文件的内容:
< "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
是否消耗所有 redirected/piped 文本数据,甚至是多行,尽管它们只显示接收到的第一个字符?他们在乱弄文件指针吗?
有没有办法防止这些命令吸收多个字符?
1 ... 最后一行以换行符终止,以便 findstr
不会无限期地挂起 – 请参阅此线程:What are the undocumented features and limitations of the Windows FINDSTR command?,第 »FINDSTR 在 XP 和 Windows 7 上挂起,如果重定向的输入不以 <LF>
«.
重定向与管道之间的行为实际上有所不同。
重定向
似乎 XCOPY 和 REPLACE 只是将标准输入文件指针移动到文件结尾 (EOF)。
如果您使用 FIND /V ""
而不是 FINDSTR "^"
,那么您将得到整个文件作为输出,因为 FIND 在启动时将文件指针重置为文件的开头。所以XCOPY运行后stdin流仍然有效,但是文件指针在EOF。
XCOPY 必须在没有实际读取所有数据的情况下移动文件指针,因为当我使用包含 0.5 GBytes 的 big.txt 时,它仍然是“瞬时的”。如果 XCOPY 在继续之前必须读取所有文件,将会有明显的延迟。
管道
我不完全理解这意味着什么,但我相信标准管道是块缓冲的。 XCOPY 和 REPLACE 在继续之前最多读取 1 个完整块,将剩余的管道数据留给 FINDSTR 读取。
我输入了一个包含 4191 个字节的 127 行文件,FINDSTR 在 3 行中输出了 97 个字节。所以在这种情况下,XCOPY 似乎读取了 4094 个字节。
然后我在没有任何新行的情况下输入了一个 5000 字节的文件,FINDSTR 输出了 908 字节,这意味着 XCOPY 似乎读取了 4092 字节。
所以管道块缓冲区必须在 4 kbytes 附近的某个地方。我的猜测是 XCOPY 只是将文件指针移动到当前缓冲区的末尾而不读取所有数据,但我不知道如何测试它。
正如预期的那样,用 FIND 代替 FINDSTR 不会改变使用管道时的结果 - 在读取数据后,无法将文件指针重置回管道数据的开头。
我无法想象有什么方法可以修改 XCOPY 或 REPLACE 的行为...就是这样。
至于为什么 XCOPY 和 REPLACE 的行为方式是这样的?......我没有任何线索。微软的“批处理”世界是如此奇特,我早就放弃了问为什么。