无缓冲的StreamReader [英] Unbuffered StreamReader

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

问题描述

有没有一种方法来保持的StreamReader从做任何缓冲?

Is there a way to keep StreamReader from doing any buffering?

我试图从可能是二进制或文本进程句柄输出。输出看起来像一个HTTP响应,如:

I'm trying to handle output from a Process that may be either binary or text. The output will look like an HTTP Response, e.g.

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

text or binary data here

我想要做的是解析使用一个标题的StreamReader ,然后将其从读取它的 BaseStream 的StreamReader 来处理内容的其余部分。这里基本上是我开始的:

What I want to do is to parse the headers using a StreamReader, and then either read from its BaseStream or the StreamReader to handle the rest of the content. Here's basically what I started with:

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());
}

这似乎垃圾二进制数据。所以我改变了最后一行是这样的:

This seems to trash binary data. So I changed the last line to something like this:

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的是什么?

... but StreamReader buffers its input, so reader.BaseStream is in the wrong position. Is there a way to unbuffer StreamReader? Or can I tell StreamReader to reset the stream back to where StreamReader is?

推荐答案

这答案是晚了,可能不再适用于你,但它可能会派上用场别人谁过这个问题失蹄。

This answer is late and possibly no longer relevant to you but it may come in handy for someone else who stumbles across this problem.

我的问题涉及的 PPM文件,其中有一个类似的格式:

My problem involved PPM files, which have a similar format of:


  • 在年初ASCII文本

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

我遇到的问题是,的StreamReader 类是无能力在一个时间无缓冲的东西读的东西一个字节。这导致在某些情况下意外的结果,因为阅读()方法读取单个字符,而不是一个字节。

The problem I ran into was that the StreamReader class is incapable of reading stuff one byte at a time without buffering stuff. This caused unexpected results in some cases, since the Read() method reads a single character, not a single byte.

我的解决办法是写周围,将在同一时间读取的字节之一的流的包装。该包装有2个重要的方法,的ReadLine()阅读()

My solution was to write a wrapper around a stream that would read bytes one at a time. The wrapper has 2 important methods, ReadLine() and Read().

这2个方法允许我读取一个流,无缓冲的ASCII码线,然后在一个时间流的其余部分读取单个字节。你可能需要做一些调整,以满足您的需求。

These 2 methods allow me to read the ASCII lines of a stream, unbuffered, and then read a single byte at a time for the rest of the stream. You may need to make some adjustments to suit your needs.

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<byte> bytes = new List<byte>();
        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();
    }
}

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

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