【发布时间】:2018-01-04 15:50:08
【问题描述】:
问题
我正在尝试将字符和/或字节数组从 CP437 encoding 转换为 UTF-8 (Encoding.UTF8)。问题是无论我尝试什么代码总是产生相同的字符代码,但是由于这两种编码有一组不同的字符映射到字符代码,因此生成的 char 是不一样的。
例如,我试图将字符代码为 3 的字符从 CP437(一颗心:♥)转换为 UTF-8,但我仍然希望它是同一个字符。但是,当转换为 UTF-8 时,它仍然使用字符代码 3,这会产生一个名为 ETX 的控制字符(有关字符列表,请参阅 UTF-8's codepage layout)。
我的尝试
以下是我的一些尝试:
(通用代码)
Public Shared ReadOnly CP437 As Encoding = Encoding.GetEncoding("IBM437")
Public Shared ReadOnly BytesToConvert As Byte() = New Byte(3 - 1) {3, 4, 5} 'Characters: ♥, ♦, ♣.
Public Sub DebugEncodedArray(ByVal Bytes As Byte(), ByVal Encoding As Encoding)
Dim ResultingString As String = Encoding.GetString(Bytes)
MessageBox.Show( _
String.Format("Encoding: {1}{0}" & _
"String: ""{2}""{0}" & _
"Bytes: {{{3}}}{0}", _
Environment.NewLine, _
Encoding.EncodingName, _
ResultingString, _
String.Join(", ", Bytes)), _
"Debug", MessageBoxButtons.OK, MessageBoxIcon.Information _
)
End Sub
Dim ConvertedBytes As Byte() = Encoding.Convert(CP437, Encoding.UTF8, BytesToConvert)
DebugEncodedArray(ConvertedBytes, Encoding.UTF8)
使用StreamWriter,使用特定编码写入MemoryStream:
Using MStream As New MemoryStream(16)
Using Writer As New StreamWriter(MStream, CP437)
Writer.Write(CP437.GetChars(BytesToConvert))
End Using
Dim UTF8Bytes As Byte() = Encoding.Convert(CP437, Encoding.UTF8, MStream.ToArray())
DebugEncodedArray(UTF8Bytes, Encoding.UTF8)
End Using
写入文件,然后读取并转换字节(对于我需要此代码的用途而言不是最佳的):
File.WriteAllText("C:\Users\Vincent\Desktop\test.txt", CP437.GetString(BytesToConvert), CP437)
Dim FileBytes As Byte() = File.ReadAllBytes("C:\Users\Vincent\Desktop\test.txt")
Dim UTF8Bytes As Byte() = Encoding.Convert(CP437, Encoding.UTF8, FileBytes)
DebugEncodedArray(UTF8Bytes, Encoding.UTF8)
结果
以上所有尝试都给出了相同的结果:
如果我将CP437 传递给DebugEncodedArray() 而不是Encoding.UTF8:
预期结果
我期待的结果是:
Dim UTF8Bytes As Byte() = Encoding.UTF8.GetBytes("♥♦♣")
DebugEncodedArray(UTF8Bytes, Encoding.UTF8)
关于我做错了什么的任何线索?
【问题讨论】:
-
低范围是上下文相关的,我认为您已经证明,对于 1-31 和 127,您将需要一个简单的查找,因为 .Net 在控制代码上下文而不是图形上下文中解释它们. (即
◙(0xA) 是\n不是该图形的等效 unicode 代码点) -
@AlexK。 : 嗯,没想到……它会将它们解释为控制字符,因此不会重新映射它们,这是有道理的。 -- 那么使用查找表是否安全?我的意思是,即使在将来,这些字符在 UTF-8 中是否总是具有相同的代码? (可能是一个愚蠢的问题,但我不太了解字符编码及其所有规格或可能的变化)
-
当然,如果您决定在看到 0xA 时进行查找和输出 ◙ 那很好。虽然这当然意味着您将无法拥有带有换行符的文本...
-
@AlexK。 : 不会有问题的。 charcode 以编程方式组成,仅应以 UTF-8 友好格式从 CP437 输出单个可显示字符。请将您的信息添加到答案中,以便我将其标记为已接受!
标签: vb.net encoding utf-8 character-encoding codepage-437