Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/powershell/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/jsf/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Powershell I';我收到一封“信”;OutOfMemoryException“;使用超过1gb的文件时_Powershell_File Get Contents - Fatal编程技术网

在Powershell I';我收到一封“信”;OutOfMemoryException“;使用超过1gb的文件时

在Powershell I';我收到一封“信”;OutOfMemoryException“;使用超过1gb的文件时,powershell,file-get-contents,Powershell,File Get Contents,在加载到数据仓库之前,我正在进行一些文件清理,遇到了一个文件大小问题: (Get-Content -path C:\Workspace\workfile\myfile.txt -Raw) -replace '\\"', '"' | Set-Content C:\Workspace\workfile\myfileCLEAN.txt 我的文件大约是2GB。我收到以下错误,不确定如何更正 获取内容:“System.OutOfMemoryException”类型的异常为 扔 我不是

在加载到数据仓库之前,我正在进行一些文件清理,遇到了一个文件大小问题:

(Get-Content -path C:\Workspace\workfile\myfile.txt -Raw) -replace '\\"', '"' | Set-Content C:\Workspace\workfile\myfileCLEAN.txt
我的文件大约是2GB。我收到以下错误,不确定如何更正

获取内容:“System.OutOfMemoryException”类型的异常为 扔


我不是一个编码员,但我喜欢学习,所以我要建立自己的数据仓库。因此,如果您确实响应了,请记住我的经验级别:)

获取内容
将整个文件加载到内存中

尝试逐行处理以提高内存利用率

$infile = "C:\Workspace\workfile\myfile.txt"
$outfile = "C:\Workspace\workfile\myfileCLEAN.txt"

foreach ($line in [System.IO.File]::ReadLines($infile)) {
    Add-Content -Path $outfile -Value ($line -replace '\\"','"')
}

Get Content-Raw
使PowerShell将整个文件读取为单个字符串

.NET无法在内存中存储大小超过2GB的单个对象,并且字符串中的每个字符占用2个字节,因此在读取前10亿个字符(大致相当于1GB ASCII编码的文本文件)后,它达到了内存限制

卸下
-Raw
开关,
-replace
完全能够同时操作多个输入字符串:

(Get-Content -path C:\Workspace\workfile\myfile.txt) -replace '\"', '"' | Set-Content C:\Workspace\workfile\myfileCLEAN.txt
请注意,
-replace
是一个正则表达式运算符,如果要从字符串中删除
\
,则需要对其进行转义:

(Get-Content -path C:\Workspace\workfile\myfile.txt) -replace '\\"', '"' | Set-Content C:\Workspace\workfile\myfileCLEAN.txt
虽然这会起作用,但仍然会很慢,因为在应用
-replace
并写入输出文件之前,我们仍在将>2GB的数据加载到内存中

相反,您可能希望通过管道将输出从
Get Content
传输到
ForEach对象
cmdlet:

Get-Content -path C:\Workspace\workfile\myfile.txt |ForEach-Object {
  $_ -replace '\\"','"'
} |Set-Content C:\Workspace\workfile\myfileCLEAN.txt
这允许
Get Content
在完成文件读取之前开始推送输出,因此PowerShell不再需要像以前那样分配大量内存,从而加快执行速度。

  • 逐行读取文本文件(无需将整个文件加载到内存中)的一种有效方法是使用带有
    -file
    参数的语句

  • 编写文本文件的有效方法是使用实例

  • 正如Mathias在中指出的,由于正则表达式的转义规则,使用基于正则表达式的逐字
    \“
    实际上会单独替换
    。虽然您可以使用
    “\\”
    解决这个问题,但在本例中,一个更简单、性能更好的替代方法是使用
    [string]
    类型的方法,该方法对文本子字符串进行操作

总而言之:

# Note: Be sure to use a *full* path, because .NET's working dir. usually
#       differs from PowerShell's.
$streamWriter = [System.IO.StreamWriter]::new('C:\Workspace\workfile\myfileCLEAN.txt')

switch -File C:\Workspace\workfile\myfile.txt {
  default { $streamWriter.WriteLine($_.Replace('\"', '"')) }
}

$streamWriter.Close()
注意:如果您使用的是旧版本的Windows PowerShell,即版本4或更低,请使用
New Object System.IO.StreamWriter'C:\Workspace\workfile\myfileCLEAN.txt'

而不是

[System.IO.StreamWriter]::新建('C:\Workspace\workfile\myfileCLEAN.txt')

不要加载整个文件…一行一行地加载它,并在每一行上进行替换。然后使用
添加内容
将结果发送到新文件。
获取内容
仅在使用
-Raw
开关或将调用包含在
(…)
中时才将整个文件加载到内存中。
[System.IO.file]::ReadLines()
是读取文件的一种有效方法,在循环中使用
添加内容
会在每次迭代中打开和关闭输出文件,这会抵消性能优势。这可以工作,但速度与使用Get Content一样慢。我看到的唯一优势是占用内存少,而且我可以更轻松地监控进度。这确实有效,但非常简单速度慢,2GB文件的处理速度快了将近一个小时。有没有任何帮助加快处理速度的提示?谢谢你指出。我升级到了v5,哇!这非常好而且非常快:)非常感谢!