Out-File
有一个默认的编码,除非与-Encoding
参数重写:通过读取试图读取它的byte order mark,并用它作为-Encoding
我做了什么来解决这个问题是试图得到原始文件的编码参数值。
下面是一个处理一堆文本文件路径,获取原始编码,处理内容并使用原始编码将其写回文件的示例。
function Get-FileEncoding {
param ([string] $FilePath)
[byte[]] $byte = get-content -Encoding byte -ReadCount 4 -TotalCount 4 -Path $FilePath
if ($byte[0] -eq 0xef -and $byte[1] -eq 0xbb -and $byte[2] -eq 0xbf)
{ $encoding = 'UTF8' }
elseif ($byte[0] -eq 0xfe -and $byte[1] -eq 0xff)
{ $encoding = 'BigEndianUnicode' }
elseif ($byte[0] -eq 0xff -and $byte[1] -eq 0xfe)
{ $encoding = 'Unicode' }
elseif ($byte[0] -eq 0 -and $byte[1] -eq 0 -and $byte[2] -eq 0xfe -and $byte[3] -eq 0xff)
{ $encoding = 'UTF32' }
elseif ($byte[0] -eq 0x2b -and $byte[1] -eq 0x2f -and $byte[2] -eq 0x76)
{ $encoding = 'UTF7'}
else
{ $encoding = 'ASCII' }
return $encoding
}
foreach ($textFile in $textFiles) {
$encoding = Get-FileEncoding $textFile
$content = Get-Content -Encoding $encoding
# Process content here...
$content | Set-Content -Path $textFile -Encoding $encoding
}
更新下面是使用StreamReader类获取原始文件的编码的一个例子。该示例读取文件的前3个字节,以便根据其内部BOM检测例程的结果设置CurrentEncoding
属性。
http://msdn.microsoft.com/en-us/library/9y86s1a9.aspx
的detectEncodingFromByteOrderMarks参数检测由 编码看的前三个字节流。如果文件以适当的字节顺序标记开始,它会自动识别UTF-8,小端Unicode和大端Unicode文本 。否则,使用UTF8Encoding 。有关更多 信息,请参阅Encoding.GetPreamble方法。
http://msdn.microsoft.com/en-us/library/system.text.encoding.getpreamble.aspx
$text = @"
This is
my text file
contents.
"@
#Create text file.
[IO.File]::WriteAllText($filePath, $text, [System.Text.Encoding]::BigEndianUnicode)
#Create a stream reader to get the file's encoding and contents.
$sr = New-Object System.IO.StreamReader($filePath, $true)
[char[]] $buffer = new-object char[] 3
$sr.Read($buffer, 0, 3)
$encoding = $sr.CurrentEncoding
$sr.Close()
#Show the detected encoding.
$encoding
#Update the file contents.
$content = [IO.File]::ReadAllText($filePath, $encoding)
$content2 = $content -replace "my" , "your"
#Save the updated contents to file.
[IO.File]::WriteAllText($filePath, $content2, $encoding)
#Display the result.
Get-Content $filePath
我已经想过这个问题,但必须有一个更简单的方法,绝不能呢?但现在这对我很有用。谢谢安迪! – Pete 2012-02-03 03:34:20
@Pete你将不得不得到编码。没有任何cmdlet可以为您提供。我更新了我的答案,添加了不同的方法。两种方式都使用BOM检测。 – 2012-02-03 05:20:13
'Set-Content -Path BOM_Utf32.txt -Value $ null -Encoding UTF32'写入_UTF-32,little-endian_ BOM,即'FF FE 00 00'字节序列。但是,函数Get-FileEncoding返回Unicode。另一方面,'00 00 FE FF'字节序列被识别为'UTF32',但按照[Unicode联盟](http://unicode.org/faq/utf_bom.html#BOM)这是_UTF-32, big-endian_ BOM。我错了吗?错误在哪里? – JosefZ 2016-05-05 21:55:41