有没有办法知道 StreamReader 使用了流的多少字节?
我有一个项目,我们需要读取一个文件,该文件具有文本标题,后跟二进制数据的开头。我最初尝试读取该文件是这样的:
private int _dataOffset;
void ReadHeader(string path)
{
using (FileStream stream = File.OpenRead(path))
{
StreamReader textReader = new StreamReader(stream);
do
{
string line = textReader.ReadLine();
handleHeaderLine(line);
} while(line != "DATA") // Yes, they used "DATA" to mark the end of the header
_dataOffset = stream.Position;
}
}
private byte[] ReadDataFrame(string path, int frameNum)
{
using (FileStream stream = File.OpenRead(path))
{
stream.Seek(_dataOffset + frameNum * cbFrame, SeekOrigin.Begin);
byte[] data = new byte[cbFrame];
stream.Read(data, 0, cbFrame);
return data;
}
return null;
}
问题是当我设置_dataOffset
to stream.Position
,我得到 StreamReader 已读取到的位置,而不是标头的末尾。我一想到这是有道理的,但我仍然需要能够知道标头的末尾在哪里,并且我不确定是否有办法做到这一点并仍然利用 StreamReader。
你可以查出有多少字节StreamReader
实际上已经以多种方式返回(而不是从流中读取),恐怕没有一种方式太简单。
- 得到结果
textReader.CurrentEncoding.GetByteCount(totalLengthOfAllTextRead)
然后在流中寻找这个位置。
- 使用一些反射黑客来检索私有变量的值
StreamReader
对应于内部缓冲区中当前字节位置的对象(与流不同 - 通常位于后面,但当然不大于等于)。从.NET Reflector来看,这个变量似乎被命名为bytePos
.
- 不用费心使用
StreamReader
根本没有,而是实现构建在之上的自定义 ReadLine 函数Stream
or BinaryReader
even (BinaryReader
保证永远不会阅读超出您要求的内容)。此自定义函数必须从流中逐个字符读取,因此您实际上必须使用低级Decoder
对象(除非编码是 ASCII/ANSI,在这种情况下,由于单字节编码,事情会更简单一些)。
选项 1 将是我想象中效率最低的(因为您有效地重新编码了刚刚解码的文本),而选项 3 最难实现,尽管可能是最优雅的。我可能会建议不要使用丑陋的反射黑客(选项2),尽管它看起来很诱人,是最直接的解决方案并且只需要几行。 (老实说,StreamReader
类确实应该通过公共属性公开这个变量,但可惜它没有。)所以最后,这取决于你,但方法 1 或 3 应该足够好地完成这项工作......
希望有帮助。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)