0

我不明白我从下面的代码中得到的结果,有人可以解释一下。仅在读取UNICODE编码的文本文件时发生。

fs = File.Open(fileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);

// read from start
byte[] lne = new byte[100];
int actual = fs.Read(lne, 0, lne.Length);
string line = Encoding.Unicode.GetString(lne, 0, actual); // ok readable stuff as expected
string line1 = Encoding.BigEndianUnicode.GetString(lne, 0, actual); // fail as expected

// move down into the file
fs.Seek(-150, SeekOrigin.End);
fs.ReadByte(); // take this out, works ok!

lne = new byte[100];
actual = fs.Read(lne, 0, lne.Length);
line = encoding.GetString(lne, 0, actual); // fail non readable stuff - NOT EXPECTED
line1 = Encoding.BigEndianUnicode.GetString(lne, 0, actual); // SUCCESS, readable - huh!

显然代码不是“真实世界”,它只是我真实代码正在做什么的细分。

在第一个 Encoding.Unicode.GetString 之后,我可以在变量“line”中看到良好的可读数据,并在“line1”中看到糟糕的数据。

在第二个 Encoding.Unicode.GetString 之后,我看到了完整的废话(我不知道日语/中文),但 line1 现在包含来自文件的可读数据。

如果我取出 ReadByte,一切都会按预期工作。

任何人都知道为什么会这样。

TIA。

4

2 回答 2

2

您正在移动到流的末尾减去 100 个字节。然后您读取一个字节(将您带到流的末尾减去 99 个字节),然后您尝试读取 100 个字节。这会将您带到流之外的一个字节。

于 2013-09-27T15:27:11.793 回答
0

Unicode 字符串是 2 个字节,对于 ASCII 字符串看起来像

0x41, 0, 0x42, 0, 0x43, 0 ...  // {ASCII code for A}, 0,...

因此,如果您以相反的顺序 ( BigEndianUnicode) 读取字节,则会得到无意义的字符。上面的字符串读作0x4100, 0x4200, 0x4300 ...而不是0x0041,...

当您以奇数偏移量开始读取(您从文件代码末尾查找)时也会发生类似情况 - 带有 ASCII 文本的字节如下所示:

0, 0x41, 0, 0x42, 0, 0x43 ...

读作0x4100, 0x4200, 0x4300...

ReadByte取出第一个 0,因此您从字符的开头而不是中间读取,并且序列变为有效的纯 ASCII Unicode 字符串(最后一个字符可能无效:

0x41, 0, 0x42, 0, 0x43,...
于 2013-09-27T16:14:28.327 回答