当前位置:  开发笔记 > 编程语言 > 正文

无缓冲的StreamReader

如何解决《无缓冲的StreamReader》经验,为你挑选了1个好方法。

有没有办法让StreamReader不做任何缓冲?

我正在尝试处理可能是二进制或文本的进程的输出.输出看起来像HTTP响应,例如

Content-type: application/whatever
Another-header: value

text or binary data here

我想要做的是使用a解析标题StreamReader,然后从其中读取BaseStreamStreamReader处理其余内容.这基本上是我开始的:

private static readonly Regex HttpHeader = new Regex("([^:]+): *(.*)");
private void HandleOutput(StreamReader reader)
{
  var headers = new NameValueCollection();
  string line;
  while((line = reader.ReadLine()) != null)
  {
    Match header = HttpHeader.Match(line);
    if(header.Success)
    {
      headers.Add(header.Groups[1].Value, header.Groups[2].Value);
    }
    else
    {
      break;
    }
  }
  DoStuff(reader.ReadToEnd());
}

这似乎是垃圾二进制数据.所以我把最后一行改成了这样的东西:

if(headers["Content-type"] != "text/html")
{
  // reader.BaseStream.Position is not at the same place that reader
  // makes it looks like it is.
  // i.e. reader.Read() != reader.BaseStream.Read()
  DoBinaryStuff(reader.BaseStream);
}
else
{
  DoTextStuff(reader.ReadToEnd());
}

...但是StreamReader缓冲了它的输入,因此reader.BaseStream处于错误的位置.有没有办法解密StreamReader?或者我可以告诉StreamReader将流重置回StreamReader所在的位置吗?



1> Dan Herbert..:

这个答案很晚,可能不再与你相关,但对于遇到这个问题的其他人来说,它可能会派上用场.

我的问题涉及PPM文件,其格式类似于:

开头的ASCII文本

文件其余部分的二进制字节

我遇到的问题是StreamReader该类无法一次读取一个字节而没有缓冲内容.在某些情况下,这会导致意外结果,因为该Read()方法读取单个字符,而不是单个字节.

我的解决方案是在流中编写一个包装器,一次读取一个字节.包装器有两个重要的方法,ReadLine()Read().

这两种方法允许我读取流的ASCII行,无缓冲,然后一次读取一个字节用于流的其余部分.您可能需要进行一些调整以满足您的需求.

class UnbufferedStreamReader: TextReader
{
    Stream s;

    public UnbufferedStreamReader(string path)
    {
        s = new FileStream(path, FileMode.Open);
    }

    public UnbufferedStreamReader(Stream stream)
    {
        s = stream;
    }

    // This method assumes lines end with a line feed.
    // You may need to modify this method if your stream
    // follows the Windows convention of \r\n or some other 
    // convention that isn't just \n
    public override string ReadLine()
    {
        List bytes = new List();
        int current;
        while ((current = Read()) != -1 && current != (int)'\n')
        {
            byte b = (byte)current;
            bytes.Add(b);
        }
        return Encoding.ASCII.GetString(bytes.ToArray());
    }

    // Read works differently than the `Read()` method of a 
    // TextReader. It reads the next BYTE rather than the next character
    public override int Read()
    {
        return s.ReadByte();
    }

    public override void Close()
    {
        s.Close();
    }
    protected override void Dispose(bool disposing)
    {
        s.Dispose();
    }

    public override int Peek()
    {
        throw new NotImplementedException();
    }

    public override int Read(char[] buffer, int index, int count)
    {
        throw new NotImplementedException();
    }

    public override int ReadBlock(char[] buffer, int index, int count)
    {
        throw new NotImplementedException();
    }       

    public override string ReadToEnd()
    {
        throw new NotImplementedException();
    }
}

推荐阅读
小色米虫_524
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有