我正在使用围绕TcpClient
构建的网络协议,使用BinaryReader
从底层NetworkStream
读取字节(相反,使用BinaryWriter
来编写)。< / p>
协议以UTF-8编码传输字符串,并调用reader.ReadString()
从流中读取它们(使用writer.Write(someStr)
写入)。
是否有一种简单的方法可以确定从NetworkStream读取(或写入)的字节数,而无需跳过箍来计算传输的字符串的实际字节长度?
请注意,BinaryWriter.Write()
在字符串的实际字节之前写入一个7位编码的整数,这使得任何手动计算更加复杂。
另请注意,NetworkStream
不支持Position
属性,因为它抱怨无法Seek
。
此外,我想避免引入必须将数据复制/扫描到读/写过程中的中介,以免影响整个系统的性能。
是否有 easy ,通过网络接口计算字节数的高级方法,而无需手动考虑字符串的编码和长度?
答案 0 :(得分:1)
您可以在网络流和读取器之间插入自定义流来计算字节数。
没有必要复制数据来做到这一点。只需将传递的字节数添加到计数器即可。
答案 1 :(得分:0)
对于那些对我如何实现字节计数流感到好奇的人来说,这里有它的所有荣耀(或者是臭名昭着的,视情况而定):
using System;
using System.IO;
namespace Streams
{
/// <summary>
/// A wrapper around a <see cref="Stream"/> that keeps track of the number of bytes read and written.
/// </summary>
public class ByteCountingStream : Stream
{
private readonly Stream inner;
private long totalBytesWritten;
private long totalBytesRead;
public ByteCountingStream(Stream inner)
{
this.inner = inner;
}
public override void Flush()
{
inner.Flush();
}
public override long Seek(long offset, SeekOrigin origin)
{
throw new NotImplementedException();
}
public override void SetLength(long value)
{
throw new NotImplementedException();
}
public override int Read(byte[] buffer, int offset, int count)
{
int readBytes = inner.Read(buffer, offset, count);
totalBytesRead += readBytes;
return readBytes;
}
public override void Write(byte[] buffer, int offset, int count)
{
inner.Write(buffer, offset, count);
totalBytesWritten += count;
}
public override bool CanRead => true;
public override bool CanSeek => false;
public override bool CanWrite => true;
public override long Length
{
get
{
throw new NotImplementedException();
}
}
public override long Position { get; set; }
public long TotalBytesWritten => totalBytesWritten;
public long TotalBytesRead => totalBytesRead;
}
}
实现将缓冲区传递给基础流,因此实际上不涉及数据复制。