首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何实现惰性流块枚举器?

如何实现惰性流块枚举器?
EN

Stack Overflow用户
提问于 2012-02-06 23:45:26
回答 2查看 1.3K关注 0票数 3

我正在尝试将字节流分割成大小不断增加的块。

源流包含未知的字节数,读取开销很大。枚举器的输出应该是大小递增的字节数组,从8KB到1MB。

这非常简单,只需读取整个流,将其存储在一个数组中,并取出相关的部分。但是,由于流可能非常大,因此一次读取它是不可行的。此外,虽然性能不是主要的关注点,但保持系统负载非常低是很重要的。

在实现这一点时,我注意到保持代码简短和可维护相对困难。还有一些与流相关的问题需要牢记(例如,即使Stream.Read成功了,它也可能不会填充缓冲区)。

我没有找到任何对我的情况有帮助的现有类,也没有在网上找到类似的东西。您将如何实现这样的类?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-02-07 00:00:09

代码语言:javascript
运行
复制
public IEnumerable<BufferWrapper> getBytes(Stream stream)
{
    List<int> bufferSizes = new List<int>() { 8192, 65536, 220160, 1048576 };
    int count = 0;
    int bufferSizePostion = 0;
    byte[] buffer = new byte[bufferSizes[0]];
    bool done = false;
    while (!done)
    {
        BufferWrapper nextResult = new BufferWrapper();
        nextResult.bytesRead = stream.Read(buffer, 0, buffer.Length);
        nextResult.buffer = buffer;
        done = nextResult.bytesRead == 0;
        if (!done)
        {
            yield return nextResult;
            count++;
            if (count > 10 && bufferSizePostion < bufferSizes.Count)
            {
                count = 0;
                bufferSizePostion++;
                buffer = new byte[bufferSizes[bufferSizePostion]];
            }
        }
    }
}

public class BufferWrapper
{
    public byte[] buffer { get; set; }
    public int bytesRead { get; set; }
}

显然,何时增加缓冲区大小以及如何选择缓冲区大小的逻辑可能会改变。

有人可能还会找到一种更好的方法来处理要发送的最后一个缓冲区,因为这不是最有效的方法。

票数 4
EN

Stack Overflow用户

发布于 2012-02-07 00:30:00

作为参考,我目前使用的实现已经根据@Servy的回答进行了改进

代码语言:javascript
运行
复制
private const int InitialBlockSize = 8 * 1024;
private const int MaximumBlockSize = 1024 * 1024;

private Stream _Stream;
private int _Size = InitialBlockSize;

public byte[] Current
{
    get;
    private set;
}

public bool MoveNext ()
{
    if (_Size < 0) {
        return false;
    }

    var buf = new byte[_Size];
    int count = 0;

    while (count < _Size) {
        int read = _Stream.Read (buf, count, _Size - count);

        if (read == 0) {
            break;
        }

        count += read;
    }

    if (count == _Size) {
        Current = buf;
        if (_Size <= MaximumBlockSize / 2) {
            _Size *= 2;
        }
    }
    else {
        Current = new byte[count];
        Array.Copy (buf, Current, count);
        _Size = -1;
    }

    return true;
}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9162760

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档