【发布时间】:2018-06-14 11:49:48
【问题描述】:
我正在处理一些非常大的文件来查找和替换字符串,所以我需要使用 StreamReader 和 StreamWriter。而且我还需要支持多种编码。我有
$reader = [IO.StreamReader]::New("\\Mac\Support\Journal Tools\Aaron\ANSI.txt")
$writer = [IO.StreamWriter]::New("\\Mac\Support\Journal Tools\Aaron\stream.txt", $reader.CurrentEncoding)
它不会引发任何类型的错误,但无论源编码是什么,输出文件始终是“System.Text.UTF8Encoding”。显然我错过了一些基本的东西,但是没有抛出的错误让我很难过。
编辑:我尝试使用上面的构造函数强制 ASCII,像这样
$writer = [IO.StreamWriter]::New("\\Mac\Support\Journal Tools\Aaron\stream.txt", [System.Text.ASCIIEncoding])
但不知何故,输出仍然是 UTF8,但没有错误。好奇者和好奇者。
编辑 2:因此,基于 cmets,我尝试强制使用 ASCII,并在此处添加了我用来查看结果文件编码为的代码。也许这就是我出错的地方?
$reader = [IO.StreamReader]::New("\\Mac\Support\Journal Tools\Aaron\ANSI.txt")
$writer = [IO.StreamWriter]::New("\\Mac\Support\Journal Tools\Aaron\stream.txt", [System.Text.Encoding]::ASCII)
try {
while (-not ($reader.EndOfStream)) {
$line = $reader.ReadLine()
$writer.WriteLine($line)
}
}
finally {
$reader.Close(); $reader.Dispose()
$writer.Close(); $writer.Dispose()
}
$reader.Close(); $reader.Dispose()
$writer.Close(); $writer.Dispose()
$test = [IO.StreamReader]::New("\\Mac\Support\Journal Tools\Aaron\stream.txt")
Write-Host "$($test.CurrentEncoding)!!!"
$test.Close(); $test.Dispose()
最终我需要能够将从 .CurrentEncoding 获得的文本表达式转换为构造函数的正确格式。是否有一些可用的功能,或者我要为该转换制作自己的表格?
嗯,奇怪。我有一个可以通过 NotePad++ 验证的文件是 UNICODE 文件,但这仍然报告 UTF8。
$reader = [IO.StreamReader]::New("\\Mac\Support\Journal Tools\Aaron\UNICODE.txt", $true)
Write-Host "$($reader.CurrentEncoding)"
$reader.Close(); $reader.Dispose()
然而,这个小函数正确地返回了 Unicode。
function Get-PxFileEncoding {
[CmdletBinding()]
param (
[parameter(Mandatory=$true)][String]$filePath
)
[Byte[]] $byte = get-content -path:$filePath -encoding:Byte -readCount:4 -totalCount:4
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'
}
$encoding
}
似乎这里可能有一个错误。其他人可以验证上面的 3 衬里是否为您返回 Unicode 吗? FWIW,这是升级到 PS5 的 Windows 7 VM。
【问题讨论】:
-
将您的
$OutputEncoding首选项变量设置为[Text.UTF8Encoding]或您的目标。 -
哇,真的没有办法直接在 $writer 对象上做,你必须使用偏好变量吗?我的理解一直是在更有针对性的方法可用时避免偏好变量。但也许没有别的办法?
-
根据the documentation,有一个
.Encoding属性,但是您需要使用正确的构造函数进行所需的编码。请参阅同一篇文章中的构造函数。 -
@Gordon 是什么让您认为
StreamReader自动检测到正确的编码? -
@Mathias,嗯,存在 CurrentEncoding 参数,以及构造函数引用文件的事实,所以我假设它会使用文件的编码。我认为我把我搞砸了? ;) 那么这应该是什么样子,才能使输出文件与源文件的编码相匹配?