【问题标题】:C# - Why StreamReader ReadLine reading data before calling ReadLine?C# - 为什么 StreamReader ReadLine 在调用 ReadLine 之前读取数据?
【发布时间】:2018-01-14 10:52:29
【问题描述】:

我在NetworkStream 上使用StreamReader,我只想读取一行或多行,另一个数据是byte array(如文件数据),我不想读取StreamReader 中的文件数据,例如我需要逐行读取文本标题,当我看到一个空行时,标题读取必须结束,接下来我必须读取文件字节, 当我用StreamReader 测试这个时,我遇到了问题,因为StreamReader 在我调用ReadLine 之前读取字节(在第一个ReadLine 之后)以及在处理StreamReader 并使用NetworkStream 读取字节之后我得到的字节块不是文件头之后的文件字节数组的开始,因为StreamReader 读取了ReadLine 中的字节块而不是调用ReadLine

StreamReader 或我的代码设置有什么问题?

using (var reader = new StreamReader(tcpClient.GetStream()))
{
    while (true)
    {
        var line = reader.ReadLine();
        headerResponse += line + "\r\n";
        if (line == "")
            break;
    }
    using (var fileStreamReader = tcpClient.GetStream())
    {
        byte[] bytes = new byte[1024];
        var readCount = fileStreamReader.Read(bytes, 0, bytes.Length);
    }
}

【问题讨论】:

  • 但是如果您不关闭流读取器并继续读取字节缓冲区,您是否正确获取数据?
  • 是的,我认为 StreamReader 读取了我不需要的数据块
  • 是什么让你认为在关闭阅读器然后重新打开阅读器后你就定位到了你离开的地方?
  • 这是一个例子,NetworkStream 只是读取下一个数据,如果你读取了一个 gon 数据块,例如,如果 headers 是 1024 字节,你从流阅读器读取 1044 字节的数据,20 字节 gon下一个流只是从 1044 位置读取字节
  • StreamReader buffers 输入,并且不能配置为不这样做。如果输入缓冲导致您出现问题(如此处所示),那么您不能使用使用缓冲的工具。

标签: c# tcpclient streamreader


【解决方案1】:

我创建了一个 CustomStreamReader 并在 ReadLine 方法中逐个读取字节并修复了我的问题:

public class CustomStreamReader : Stream
{
    NetworkStream CurrentStream { get; set; }

    public CustomStreamReader(NetworkStream currentStream)
    {
        CurrentStream = currentStream;
    }

    public override bool CanRead => CurrentStream.CanRead;

    public override bool CanSeek => CurrentStream.CanSeek;

    public override bool CanWrite => CurrentStream.CanWrite;

    public override long Length => CurrentStream.Length;

    public override long Position { get => CurrentStream.Position; set => CurrentStream.Position = value; }

    public override void Flush()
    {
        CurrentStream.Flush();
    }

    public override int Read(byte[] buffer, int offset, int count)
    {
        return CurrentStream.Read(buffer, offset, count);
    }

    public override long Seek(long offset, SeekOrigin origin)
    {
        return CurrentStream.Seek(offset, origin);
    }

    public override void SetLength(long value)
    {
        CurrentStream.SetLength(value);
    }

    public override void Write(byte[] buffer, int offset, int count)
    {
        CurrentStream.Write(buffer, offset, count);
    }

    public string ReadLine()
    {
        List<byte> result = new List<byte>();
        do
        {
            int data = CurrentStream.ReadByte();
            if (data == -1)
                break;
            result.Add((byte)data);
            if (data == 13)
            {
                data = CurrentStream.ReadByte();
                if (data == -1)
                    break;
                result.Add((byte)data);
                if (data == 10)
                    break;
            }
        }
        while (true);
        return Encoding.UTF8.GetString(result.ToArray());
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-15
    • 1970-01-01
    相关资源
    最近更新 更多