You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET中读取完整Stream后如何测量其长度?

在.NET中读取未知长度Stream后获取总长度的简便方案

如果你不想用复杂的包装器,也不想把Stream内容存入内存,有两种极简方案可以实现:

方案一:读取时实时统计字节数

这是最直接的方式——在读取Stream的循环过程中,直接累加每次读取到的字节数,读取完成后这个累加值就是总长度。完全不需要额外的包装类,代码侵入性极低。

示例代码:

long totalBytes = 0;
var buffer = new byte[4096]; // 缓冲区大小可根据实际场景调整,比如8192
int bytesRead;

while ((bytesRead = stream.Read(buffer, 0, buffer.Length)) > 0)
{
    // 在这里处理读取到的内容,比如写入文件、传递给业务逻辑
    ProcessReceivedData(buffer, bytesRead);
    totalBytes += bytesRead;
}

// 读取完成后,totalBytes就是整个Stream的总长度

方案二:极简计数包装Stream

如果你的读取逻辑是封装好的(比如需要把Stream传给第三方方法处理),不想修改原有读取代码,可以写一个超轻量的包装Stream,仅负责统计读取的字节数,比CryptoStream的实现简单得多。

计数Stream实现:

public class CountingStream : Stream
{
    private readonly Stream _innerStream;
    public long TotalBytesRead { get; private set; }

    public CountingStream(Stream innerStream)
    {
        _innerStream = innerStream ?? throw new ArgumentNullException(nameof(innerStream));
    }

    public override int Read(byte[] buffer, int offset, int count)
    {
        int bytesRead = _innerStream.Read(buffer, offset, count);
        if (bytesRead > 0)
            TotalBytesRead += bytesRead;
        return bytesRead;
    }

    // 以下方法直接委托给内部Stream,无需额外逻辑
    public override bool CanRead => _innerStream.CanRead;
    public override bool CanSeek => _innerStream.CanSeek;
    public override bool CanWrite => _innerStream.CanWrite;
    public override long Length => _innerStream.Length;
    public override long Position { get => _innerStream.Position; set => _innerStream.Position = value; }
    public override void Flush() => _innerStream.Flush();
    public override long Seek(long offset, SeekOrigin origin) => _innerStream.Seek(offset, origin);
    public override void SetLength(long value) => _innerStream.SetLength(value);
    public override void Write(byte[] buffer, int offset, int count) => _innerStream.Write(buffer, offset, count);
    protected override void Dispose(bool disposing)
    {
        if (disposing)
            _innerStream.Dispose();
        base.Dispose(disposing);
    }
}

使用方式:

using var countingStream = new CountingStream(yourOriginalStream);

// 调用原有读取逻辑处理countingStream
YourExistingReadLogic(countingStream);

// 读取完成后获取总长度
long totalLength = countingStream.TotalBytesRead;

两种方案都完全符合你的要求:不需要将Stream内容存入内存,实现简单直接,避免了复杂包装器的冗余代码。

内容的提问来源于stack exchange,提问作者Ykok

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 13:35:20