1

从大文件创建小文件时发生“System.OutOfMemoryException”错误。

我通常使用下面的 PowerShell 命令来创建一个大文件的小版本,

Get-Content input_file_name.Tmp -TotalCount 100 | Out-File -Encoding Default "output_file_name_100.Tmp"

但是,这会引发“System.OutOfMemoryException”错误。对此有何建议?

注意:它更早地适用于更大的文件。我认为文件的大小不是问题。

4

1 回答 1

1

我知道您个人认为文件的大小可能不是真正的问题,但为了其他读者的利益,值得重新审视基础知识。

Get-Content,当在管道中使用时,一次从文件中读取一行

这种逐个对象的处理是 PowerShell 管道的核心功能,并充当内存节流阀(无需一次将所有输入读入内存。

只有三种情况将整个Get-Content文件读入内存

  • 如果您在变量( ) 中捕获Get-Content的输出,在这种情况下,该变量会接收一个包含所有行的数组$content = Get-Content ...

  • 如果您将Get-Content调用括在(...)$(...)@(...)中,它也会返回一个包含所有行的数组。

  • 如果您使用-Raw开关,则Get-Content返回单个多行字符串。


使用-TotalCount 100(or -First 100) 不会改变这个基本行为:在100读取行之后,Get-Content停止读取并关闭文件。

因此,您问题中的代码无法解释您的症状-您不应耗尽内存-至少不是因为输入文件很大;如果它仍然发生,您可能会看到一个错误。

如果您有可重现的案例,我鼓励您在Windows PowerShell UserVoice 论坛中提交错误,或者,如果您可以(也)在 PowerShell [Core] v6+ 中重现错误,请在PowerShell Core GitHub存储库中提交。


同时,您可以考虑直接使用 .NET,这通常也 比使用 PowerShell 的 cmdlet更快

[Linq.Enumerable]::Take([IO.File]::ReadLines("$PWD/input_file_name.Tmp"), 100) |
  Out-File -Encoding Default output_file_name_100.Tmp

注意:
• 将"$PWD/"用作输入文件路径的一部分,因为 .NET 的工作目录通常与 PowerShell 的不同。
• 在 PowerShell 类型文字 ( [...]) 中,System.可以省略完整类型名称的部分;因此[Linq.Enumerable]System.Linq.Enumerable[IO.File]_System.IO.File

于 2020-08-05T17:07:30.700 回答