【问题标题】:Remove top line of a huge (300M) text file with powershell使用 powershell 删除一个巨大(300M)文本文件的顶行
【发布时间】:2014-07-30 19:46:51
【问题描述】:

这个问题和Remove Top Line of Text File with Powershell的区别在于我的文件很大(超过300M)。

我现在使用的技术是基于one of the answers 对那个问题的,但是对于大文件来说它似乎效率低下。有没有更快(但不那么漂亮)的方法呢?

【问题讨论】:

    标签: powershell file-io


    【解决方案1】:

    尝试使用流式读取器和流式写入器。这应该会很快执行。

    $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()
    

    【讨论】:

      【解决方案2】:

      正如安迪的回答,StreamWriter 是要走的路。 但是,我看到使用 gc $file -ReadCount 0Measure-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。根据可用内存的大小,它可能会导致内存不足异常。
      • 是的,毫无疑问它会增加内存使用量。在 PowerShell 之前我尝试过的大文件中,文件大小会增长超过 3 倍(这是一个我想知道答案的问题),但是对于这样大小的文件,我认为它是一个服务器环境,这意味着它拥有大量资源和首选性能。
      猜你喜欢
      • 1970-01-01
      • 2020-04-10
      • 2012-08-23
      • 2020-08-05
      • 2022-11-11
      • 1970-01-01
      • 1970-01-01
      • 2015-09-26
      • 2021-11-01
      相关资源
      最近更新 更多