【问题标题】:StreamWriter encodingStreamWriter 编码
【发布时间】: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 参数,以及构造函数引用文件的事实,所以我假设它会使用文件的编码。我认为我把我搞砸了? ;) 那么这应该是什么样子,才能使输出文件与源文件的编码相匹配?

标签: powershell streamwriter


【解决方案1】:

[System.Text.ASCIIEncoding][type] 类型的对象。您需要一个编码类型的对象。试试[System.Text.Encoding]::ASCII[System.Text.ASCIIEncoding]::ASCII[System.Text.ASCIIEncoding]::new()

$writer = [IO.StreamWriter]::New("\\Mac\Support\Journal Tools\Aaron\stream.txt", [System.Text.ASCIIEncoding]::ASCII)

【讨论】:

  • 我想我一定是做错了什么,因为 [System.Text.Encoding]::ASCII 不起作用。请参阅 OP 以获取修改后的代码,显示我如何在 Write 后检查编码。也许这就是我出错的地方。
  • @Gordon 你读过the docFile.IO.StreamReader 吗?如果您不提供构造函数重载类,则类假定 UTF-8 编码。另请注意,UTF-8 是 ASCII 的严格超集
  • 是的,我认为我使用了正确的重载 $writer = [IO.StreamWriter]::New("\\Mac\Support\Journal Tools\Aaron\stream.txt", [ System.Text.Encoding]::ASCII) 但是我在 .NET 方面的技能相当薄弱,所以也许我误解了文档的那一部分?
  • @Gordon 这对 Writer 来说是一个正确的重载。但是,您通过打开阅读器来“验证”它。好吧,阅读器 also 默认为 UTF-8,除非您另有说明。您可以ask StreamReader to auto-detect the encoding,但默认情况下它假定为 UTF-8。
  • @Gordon 试试[IO.StreamReader]::New("\\Mac\Support\Journal Tools\Aaron\stream.txt", $true)。但是,您可能仍会使用 UTF-8,因为 UTF-8 是传统 ASCII 的严格超集(即,不包括扩展的 ASCII 字符 128-255)。
猜你喜欢
  • 1970-01-01
  • 2015-03-10
  • 2019-03-02
  • 2012-10-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-04-28
  • 2023-03-25
相关资源
最近更新 更多