【发布时间】:2014-07-30 19:46:51
【问题描述】:
这个问题和Remove Top Line of Text File with Powershell的区别在于我的文件很大(超过300M)。
我现在使用的技术是基于one of the answers 对那个问题的,但是对于大文件来说它似乎效率低下。有没有更快(但不那么漂亮)的方法呢?
【问题讨论】:
标签: powershell file-io
这个问题和Remove Top Line of Text File with Powershell的区别在于我的文件很大(超过300M)。
我现在使用的技术是基于one of the answers 对那个问题的,但是对于大文件来说它似乎效率低下。有没有更快(但不那么漂亮)的方法呢?
【问题讨论】:
标签: powershell file-io
尝试使用流式读取器和流式写入器。这应该会很快执行。
$reader = [IO.File]::OpenText("C:\Users\Andy\Documents\input.txt")
$writer = New-Object System.IO.StreamWriter("C:\Users\Andy\Documents\output.txt")
$reader.ReadLine() > $null # Skip first line.
while ($reader.Peek() -ge 0) {
$writer.writeline($reader.ReadLine())
}
$reader.Close()
$writer.Close()
我通过创建一个 300MB 的文本文件进行了测试,并在其上使用了它。 output.txt 是在 3.5 秒内创建的 :-)。
更新我稍微优化了它,所以它不会在循环的每次迭代中都不评估表达式。现在它在 2.9 秒内完成 :-)
如果您不介意内存膨胀,您也可以这样做。这仍然更快,但占用更多内存,但比 Get-Content 少。
$reader = [IO.File]::OpenText("C:\Users\Andy\Documents\input.txt")
$writer = New-Object System.IO.StreamWriter("C:\Users\Andy\Documents\output.txt")
$reader.ReadLine() > $null # Skip first line.
$writer.write($reader.ReadToEnd())
$reader.Close()
$writer.Close()
【讨论】:
正如安迪的回答,StreamWriter 是要走的路。
但是,我看到使用 gc $file -ReadCount 0 的 Measure-Command 比使用 StreamReader 的结果更好。
$contents=gc C:\My\File.txt -ReadCount 0
$w=New-Object System.IO.StreamWriter("C:\My\File.txt")
foreach($line in $contents){if(!$f++){continue}$w.WriteLine($line)}
这还有一个额外的好处,就是能够读取和写入同一个文件。
【讨论】:
ReadCount 0 会将所有内容加载到内存中,这会使 PowerShell 相当膨胀。它对我来说高达 720MB。根据可用内存的大小,它可能会导致内存不足异常。