使用BinaryReader读取“小端UTF-16编码字符串”

3
我正在遵循这个文件格式的规范: https://github.com/rouault/dump_gdbtable/wiki/FGDB-Spec
utf16: string in little-endian UTF-16 encoding

我该如何读取这个?我尝试了BinaryReader.ReadString(),但它返回的是类似以下内容的东西:
"\0e\0y\0w\0o\0r\0d\0\0 \0\0\0\0\rP\0a\0r\0a\0m\0e\0t\0e\0r\0N\0a\0m\0e\0\0 \0\0\0\0\fC\0o\0n\0f\0i\0g\0S\0t\0r\0"

这绝对不是正确的。
从规范中:
ubyte: number of UTF-16 characters (not bytes) of the name of the field
utf16: name of the field
ubyte: number of UTF-16 characters (not bytes) of the alias of the field. Might be 0
utf16: alias of the field (ommitted if previous field is 0)
ubyte: field type ( 0 = int16, 1 = int32, 2 = float32, 3 = float64, 4 = string, 5 = datetime, 6 = objectid, 7 = geometry, 8 = binary, 9=raster, 10/11 = UUID, 12 = XML )

我能否通过UTF-16字符的数量来读取字段名称?

你如何构造BinaryReader?你是否使用了指定文本编码的重载? - Damien_The_Unbeliever
通常您需要指定编码,但在这个页面上(http://msdn.microsoft.com/en-us/library/system.text.encoding.aspx)没有小端UTF-16,也许您需要自己创建编码方式(或其中一个**是**您需要的,不确定)。 - Sinatr
BinaryReader br = new BinaryReader(File.Open("C:\florida.gdb\a00000002.gdbtable", FileMode.Open, FileAccess.Read, FileShare.Read | FileShare.Delete));二进制读取器br = new BinaryReader(File.Open(“C:\ florida.gdb \ a00000002.gdbtable”,FileMode.Open,FileAccess.Read,FileShare.Read | FileShare.Delete)); - Evan Parsons
@Sinatr - 有这样一种编码方式。它有助于了解在Windows世界中,“Unicode”意味着UTF-16。 - Damien_The_Unbeliever
你有示例文件吗? - Lasse V. Karlsen
2个回答

3
BinaryReaderReadString()方法没有提供重载,您无法指定字符串长度(它假定已编码的前缀长度,这与您链接的规范格式不匹配)。

因此,您不能直接使用ReadString(),但是您可以:
  1. 使用ReadByte()获取字符串(字符)长度,
  2. 将其乘以2,
  3. 使用ReadBytes(count)
  4. 使用Encoding.Unicode.GetString(bytes)

乘以二是必要的吗?当我这样做时,它会返回类似于下面的答案,只不过后面跟着更多的中文/日文字符:代码示例 bit = int count = (br.ReadByte() * 2) ; byte[] array = br.ReadBytes(count); field.nameOfField = Encoding.Unicode.GetString(array); - Evan Parsons
规格说明的字符数,而不是字节数。由于Encoding.Unicode是16位(每个字符2字节),因此您需要乘以2。您可能希望在问题中提供代码,以说明您如何尝试读取字符串。 - CSharpie
啊哈!我想就是这样了!它返回“关键字”,我相信这是字段的名称。 - Evan Parsons

1

它应该

BinaryReader br = new BinaryReader(File.Open("C:\\florida.gdb\\a00000002.gdbtable",
                                   FileMode.Open,
                                   FileAccess.Read,
                                   FileShare.Read | FileShare.Delete),
                      Encoding.Unicode);

其中 EncodingSystem.Text.Encoding


由于各种历史原因,Microsoft/Windows将UTF-16(特别是小端序变体)称为“Unicode”,而不是UTF-16。


当我将它切换到你的编码时,它返回“攀礀眀漀爀搀\0 \0ЀഀParameterNameЀ \0䌌漀渀昀椀最匀琀爀”。我需要去掉其他字符吗?我可以这样做,但我担心再次保存时会丢失它们。 - Evan Parsons
如果你得到了这样的返回,几乎肯定有些问题。 - Lasse V. Karlsen
文件格式不是这样工作的!您必须在特定偏移处读取字节,然后将它们解释为Unicode。 - CSharpie

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