我这里有一些Powershell代码,允许我在单行文本文件中为每个500个字符的部分添加一串字符。
[system.io.stream]$stream = [system.io.File]::OpenRead($path)
$number_of_sections = $stream.length / 500
$count = 0
[Byte[]] $section_bytes = New-Object byte[] 500
while($count -lt $number_of_sections) {
[Void]$stream.Read($section_bytes, 0 ,500)
$thisLine = [System.Text.ASCIIEncoding]::ASCII.GetString($section_bytes)
$section = $thisLine.Substring(0,500)
$string_to_be_added += "example string" + $section
$count++
}
[Byte[]] $get_bytes = [System.IO.File]::ReadAllBytes($string_to_be_added)
$write_bytes = [System.IO.File]::WriteAllBytes($write_path, $get_bytes)
现在这段代码一个字节一个字节地读取文本文件中的大单行。当我试图读写非常大的文件(60MB以上)时,就会出现这个问题。这个脚本大约需要30分钟来执行,这太慢了,而且占用了很多内存。
是否有另一种方法或更新我的代码,这将允许我更快地处理文件,并更有效地将我的字符串添加到每个500字符段?谢谢。
- 使用正确处理文本文件的StreamReader和StreamWriter
- 不要累积输出,立即写入
#$outputEncoding = [Text.Encoding]::ASCII
$outputEncoding = [Text.UTF8Encoding]::new($false), #UTF8 without BOM
$reader = [IO.StreamReader]::new('r:1.txt')
$writer = [IO.StreamWriter]::new('r:2.txt',
$false, # don't append
$outputEncoding,
10MB) # write-back cache
$buf = [char[]]::new(500)
while (!$reader.EndOfStream) {
$nRead = $reader.Read($buf, 0, $buf.length)
$writer.Write('example string')
$writer.Write($buf, 0, $nRead)
}
$reader.Close()
$writer.Close()
如果你真的需要在变量中积累文本以便以后使用它,请使用StringBuilder:
$reader = [IO.StreamReader]::new('r:1.txt')
$buf = [char[]]::new(500)
$prefix = 'example string'
$outputSize = $reader.BaseStream.Length * (1 + $prefix.Length / 500)
$text = [Text.StringBuilder]::new([int]$outputSize) # allocate memory
while (!$reader.EndOfStream) {
$nRead = $reader.Read($buf, 0, $buf.length)
$text.Append($prefix) >$null
$text.Append($buf, 0, $nRead) >$null
}
$reader.Close()
$newText = $text.ToString()
下面是一个使用regexp的例子:
$prefix = 'example string'
$prefixRX = $prefix.Replace('$', '$$') # escape special sequences like $& etc.
# see https://msdn.microsoft.com/ewy2t5e0
$prefix + ([IO.File]::ReadAllText('r:1.txt') -replace '(?s).{500}', ('$&' + $prefixRX)) |
Out-File 'r:2.txt' -Encoding utf8