FileStream Seek / ReadByte似乎颠倒了文件的字节顺序

时间:2013-09-27 15:23:28

标签: c# unicode stream unicode-string

我不明白我从下面的黑客代码中得到的结果,有人可以解释一下。只有在阅读 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之后,我看到完整的废话(japenese / chinese我不知道),但是line1现在包含来自文件的可读数据。

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

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

TIA。

2 个答案:

答案 0 :(得分:2)

您正在移动到流的末尾减去100个字节。然后你读取一个字节(它带你到流的末尾减去99个字节),然后你试图读取100个字节。这需要你在流外面一个字节。

答案 1 :(得分: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-only Unicode字符串(可能无效的最后一个字符:

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