以下 Powershell 命令无法复制整个文件;最后总是缺少一些字符。
[System.IO.StreamWriter]::new('C:\TEMP\b.csv', [System.Text.Encoding]::UTF8).Write([System.IO.StreamReader]::new('C:\Temp\a.csv', [System.Text.Encoding]::GetEncoding('iso-8859-1')).ReadToEnd())
我怀疑这是因为编写器没有刷新最后一位,因为这确实复制了整个文件:
$X = [System.IO.StreamReader]::new('C:\Temp\a.csv', [System.Text.Encoding]::GetEncoding('iso-8859-1'))
$Y = [System.IO.StreamWriter]::new('C:\TEMP\b.csv', [System.Text.Encoding]::UTF8)
$Y.Write($X.ReadAll())
$X.Dispose()
$Y.Dispose()
是否可以在没有创建变量来引用它们的情况下处理(和刷新)读取器和写入器?
编辑: 我使用流读取器/写入器尝试了这种单线器,希望读取器的读取缓冲区会直接传输到写入器的写入缓冲区,而不是等待读取器将整个文件读入内存然后写入。什么技术可以做到这一点?
我个人发现不声明一次性对象的代码通常更简洁/更简洁,但我的重点是了解对象是否/如何处理自己,而不是样式。
没有需要避开变量或写在一行上,但这种行为不是我所期望的。在 VBA 中,可以像这样复制文件并相信它会正确处理自己,而无需声明变量并显式刷新(我认为)。
Sub Cpy()
With New Scripting.FileSystemObject
.CreateTextFile("c:\Temp\Out.txt").Write .OpenTextFile("C:\Temp\In.txt", ForReading).ReadAll
End With
End Sub
通过在 Class_Terminate()
过程中编写适当的“清理”代码,可以在自定义 VBA 类中实现类似的行为。我假设 Streamwriter 将在终止时通过垃圾收集类似地刷新数据,一旦该行执行并且不再有与之关联的变量。
我还注意到该文件仍处于锁定状态,在关闭 powershell session 之前我无法删除它。有没有办法在没有声明要使用的变量的情况下刷新内容并释放文件?
最佳答案
只是为了向您展示,使用 System.IO.File
的静态方法,这是可能的,而且更容易做到。 , WriteAllText()
和 ReadAllText()
.
以下查询 https://loripsum.net/使用 iso-8859-1
编码获取随机段落并写入文件的 API。然后读取该文件并使用相同的编码写入副本,最后比较两个文件哈希。如您所见,阅读和写作都是一条线完成的。
using
语句可以删除,但您需要使用完全限定类型名称。
将位置设置为临时文件夹以进行测试。
using namespace System.IO
using namespace System.Text
$fileRead = [Path]::Combine($pwd.Path, 'test.txt')
$fileWrite = [Path]::Combine($pwd.Path, 'test-copy.txt')
$content = Invoke-RestMethod 'https://loripsum.net/api/5/short/headers/plaintext'
$encoding = [Encoding]::GetEncoding('iso-8859-1')
[File]::WriteAllText($fileRead, $content, $encoding)
[File]::WriteAllText($fileWrite, [File]::ReadAllText($fileRead, $encoding), $encoding)
(Get-FileHash $fileRead).Hash -eq (Get-FileHash $fileWrite).Hash # => Should be True
$fileRead, $fileWrite | Remove-Item
关于.net - 处理 StreamWriter 而不在一行中声明变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70721821/