优化内存的PowerShell Out-File -Encoding utf8,适用于大文件且无BOM

3

所以我在Powershell中运行外部命令,将mysqldump.exe的输出导入到一个.sql文件中。

& "C:\Program Files\MySQL\MySQL Server 5.6\bin\mysqldump.exe" @arguments | Out-File -Encoding utf8 $backupFilePath\$database.sql

首先,该文件采用UCS2编码。我发现可以在Out-File命令中设置编码为“-Encoding utf8”。但是它会添加字节顺序标记。有没有办法明确指定不想要字节顺序标记呢?

我尝试使用WriteAllLines转换文件,但是这个数据库.sql文件非常大,大小达到3GB,并且会导致内存溢出。

有什么想法吗?


4
我相信这个问题在这里已经得到了回答。https://dev59.com/SG035IYBdhLWcg3wJcjT - Sunny Chakraborty
你的字符是否超出了ASCII范围?如果没有,使用“-enc ascii”。 - Keith Hill
1
正如OP所指出的那样,使用WriteAllLines不是输出这么大(约3GB)的好选择。 - Keith Hill
是的,我确实有ASCII范围之外的字符。最终我做的是从我的Powershell脚本中调用一个批处理脚本。虽然不是很好的解决方案,但至少它能工作。如果有人有解决这个问题的方法,我非常想听听! - Mike
对于那些不了解的人来说,BOM表示字节顺序标记。这是三个字符,位于文件开头(0xEF、0xBB、0xBF),看起来像“”。 - Signal15
1个回答

0
Function Out-FileUtf8NoBom {

  [CmdletBinding()]
  param(
    [Parameter(Mandatory, Position=0)] [string] $LiteralPath,
    [switch] $Append,
    [switch] $NoClobber,
    [AllowNull()] [int] $Width,
    [Parameter(ValueFromPipeline)] $InputObject
  )

  [Environment]::CurrentDirectory = $PWD
  $LiteralPath = [IO.Path]::GetFullPath($LiteralPath)

  if ($NoClobber -and (Test-Path $LiteralPath)) { 
    Throw [IO.IOException] "The file '$LiteralPath' already exists."
  }

  $sw = New-Object IO.StreamWriter $LiteralPath, $Append

  $htOutStringArgs = @{}
  if ($Width) {
    $htOutStringArgs += @{ Width = $Width }
  }

  try {
    $Input | Out-String -Stream @htOutStringArgs | % { $sw.WriteLine($_) }
  } finally {
    $sw.Dispose()
  }

}


Function FixEncoding([string] $path)
{
    [IO.SearchOption] $option = [IO.SearchOption]::AllDirectories;
    [String[]] $files = [IO.Directory]::GetFiles((Get-Item $path).FullName, '*.*', $option);
    foreach($file in $files)
    {
        "Converting $file...";
        Get-Content $file | Out-FileUtf8NoBom $file
    }
}

你可以使用它作为FixEncoding("C:\path\to\files\")

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接