StreamReader消耗的字节 [英] Bytes consumed by StreamReader

查看:23
本文介绍了StreamReader消耗的字节的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有没有办法知道StreamReader使用了多少字节的流?

Is there a way to know how many bytes of a stream have been used by StreamReader?

我有一个项目,我们需要读取一个文件,该文件的文本标题为二进制数据的开头.我最初尝试读取此文件的过程是这样的:

I have a project where we need to read a file that has a text header followed by the start of the binary data. My initial attempt to read this file was something like this:

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 设置为 stream.Position 时,我得到了StreamReader读取到的位置,而不是标题的末尾.我一想到它就很有意义,但是我仍然需要能够知道标头的末尾在哪里,而且我不确定是否有办法做到这一点,并且仍然可以利用StreamReader.

The problem is that when I set _dataOffset to stream.Position, I get the position that the StreamReader has read to, not the end of the header. As soon as I thought about it this made sense, but I still need to be able to know where the end of the header is and I'm not sure if there's a way to do it and still take advantage of StreamReader.

推荐答案

您可以通过多种方式找出 StreamReader 实际上返回了多少字节(与从流中读取相反).,恐怕它们都不是那么简单.

You can find out how many bytes the StreamReader has actually returned (as opposed to read from the stream) in a number of ways, none of them too straightforward I'm afraid.

  1. 获取 textReader.CurrentEncoding.GetByteCount(totalLengthOfAllTextRead)的结果,然后搜索流中的该位置.
  2. 使用一些反射黑客来获取 StreamReader 对象的私有变量的值,该对象对应于内部缓冲区中的当前字节位置(与流中的当前字节位置不同-通常在后面,但没有当然不止等于).通过.NET Reflector判断,此变量似乎被命名为 bytePos .
  3. 完全不用使用 StreamReader ,而是实现在 Stream BinaryReader 之上构建的自定义ReadLine函数,即使(保证 BinaryReader 绝不会超出您的要求.这个自定义函数必须逐个char从流中读取,因此您实际上必须使用低级的 Decoder 对象(除非编码为ASCII/ANSI,在这种情况下事情会更简单一些)由于是单字节编码).
  1. Get the result of textReader.CurrentEncoding.GetByteCount(totalLengthOfAllTextRead) and then seek to this position in the stream.
  2. Use some reflection hackery to retrieve the value of the private variable of the StreamReader object that corresponds to the current byte position within the internal buffer (different from that with the stream - usually behind, but no more than equal to of course). Judging by .NET Reflector, the this variable seems to be named bytePos.
  3. Don't bother using a StreamReader at all but instead implement your custom ReadLine function built on top of the Stream or BinaryReader even (BinaryReader is guaranteed never to read further ahead than what you request). This custom function must read from the stream char by char, so you'd actually have to use the low-level Decoder object (unless the encoding is ASCII/ANSI, in which case things are a bit simpler due to single-byte encoding).

选项1将是我想象中效率最低的(因为您正在有效地重新编码刚解码的文本),选项3是最难实现的,尽管也许是最优雅的.我可能会建议您不要使用丑陋的反射技巧(选项2),尽管它看起来很诱人,它是最直接的解决方案,并且只用了几行.(说实话, StreamReader 类确实应该通过公共属性公开此变量,但是可惜没有.)因此,最终由您决定,但是方法1或3应该做得很好...

Option 1 is going to be the least efficient I would imagine (since you're effectively re-encoding text you just decoded), and option 3 the hardest to implement, though perhaps the most elegant. I'd probably recommend against using the ugly reflection hack (option 2), even though it's looks tempting, being the most direct solution and only taking a couple of lines. (To be quite honest, the StreamReader class really ought to expose this variable via a public property, but alas it does not.) So in the end, it's up to you, but either method 1 or 3 should do the job nicely enough...

希望有帮助.

这篇关于StreamReader消耗的字节的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆