如何向用户公开我的流的子部分

How to expose a sub section of my stream to a user(如何向用户公开我的流的子部分)
本文介绍了如何向用户公开我的流的子部分的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

问题描述

我有一个包含许多数据的流.我只想在另一个流中公开该数据的一部分.我要提取的数据通常超过 100mb.由于我已经有了包含数据的流,因此将该数据复制到另一个流并返回它似乎是一种浪费.我正在寻找一种方法来引用第一个流中的数据,同时控制第二个流可以引用的数据量.这可能吗

I have a stream that contains many pieces of data. I want to expose just a piece of that data in another stream. The piece of data I want to extract can often be over 100mb. Since I already have stream with the data in it it seems like a waste to copy that data to another stream and return that. What im looking for is a way to reference the data in the first stream while controlling how much of it the second stream can reference. Is this possible

推荐答案

Mark Gravell 对此进行了很好的实施 在此处详细说明.贴在那里的代码是:

There is a good implementation of this by Mark Gravell detailed here. The code posted there is:

using System.IO;
using System;
static class Program
{

 // shows that we can read a subset of an existing stream...
    static void Main()
    {
        byte[] buffer = new byte[255];
        for (byte i = 0; i < 255; i++)
        {
            buffer[i] = i;
        }
        using(MemoryStream ms = new MemoryStream(buffer))
        using (SubStream ss = new SubStream(ms, 10, 200))
        {
            const int BUFFER_SIZE = 17; // why not...
            byte[] working = new byte[BUFFER_SIZE];
            int read;
            while ((read = ss.Read(working, 0, BUFFER_SIZE)) > 0)
            {
                for (int i = 0; i < read; i++)
                {
                    Console.WriteLine(working[i]);
                }
            }
        }
    }
}

class SubStream : Stream
{
    private Stream baseStream;
    private readonly long length;
    private long position;
    public SubStream(Stream baseStream, long offset, long length)
    {
        if (baseStream == null) throw new ArgumentNullException("baseStream");
        if (!baseStream.CanRead) throw new ArgumentException("can't read base stream");
        if (offset < 0) throw new ArgumentOutOfRangeException("offset");

        this.baseStream = baseStream;
        this.length = length;

        if (baseStream.CanSeek)
        {
            baseStream.Seek(offset, SeekOrigin.Current);
        }
        else
        { // read it manually...
            const int BUFFER_SIZE = 512;
            byte[] buffer = new byte[BUFFER_SIZE];
            while (offset > 0)
            {
                int read = baseStream.Read(buffer, 0, offset < BUFFER_SIZE ? (int) offset : BUFFER_SIZE);
                offset -= read;
            }
        }
    }
    public override int Read(byte[] buffer, int offset, int count)
    {
        CheckDisposed();
        long remaining = length - position;
        if (remaining <= 0) return 0;
        if (remaining < count) count = (int) remaining;
        int read = baseStream.Read(buffer, offset, count);
        position += read;
        return read;
    }
    private void CheckDisposed()
    {
        if (baseStream == null) throw new ObjectDisposedException(GetType().Name);
    }
    public override long Length
    {
        get { CheckDisposed(); return length; }
    }
    public override bool CanRead
    {
        get { CheckDisposed(); return true; }
    }
    public override bool CanWrite
    {
        get { CheckDisposed(); return false; }
    }
    public override bool CanSeek
    {
        get { CheckDisposed(); return false; }
    }
    public override long Position
    {
        get {
            CheckDisposed();
            return position;
        }
        set { throw new NotSupportedException(); }
    }
    public override long Seek(long offset, SeekOrigin origin)
    {
        throw new NotSupportedException();
    }
    public override void SetLength(long value)
    {
        throw new NotSupportedException();
    }
    public override void Flush()
    {
        CheckDisposed(); baseStream.Flush();
    }
    protected override void Dispose(bool disposing)
    {
        base.Dispose(disposing);
        if (disposing)
        {
            if (baseStream != null)
            {
                try { baseStream.Dispose(); }
                catch { }
                baseStream = null;
            }
        }
    }
    public override void Write(byte[] buffer, int offset, int count)
    {
        throw new NotImplementedException();
    }
}

这篇关于如何向用户公开我的流的子部分的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

本站部分内容来源互联网,如果有图片或者内容侵犯了您的权益,请联系我们,我们会在确认后第一时间进行删除!

相关文档推荐

How to know if a field is numeric in Linq To SQL(如何在 Linq To SQL 中知道字段是否为数字)
Extract sql query from LINQ expressions(从 LINQ 表达式中提取 sql 查询)
LINQ Where in collection clause(LINQ Where in collection 子句)
Orderby() not ordering numbers correctly c#(Orderby() 没有正确排序数字 c#)
Why do I get quot;error: ... must be a reference typequot; in my C# generic method?(为什么我会收到“错误:...必须是引用类型?在我的 C# 泛型方法中?)
Strange LINQ Exception (Index out of bounds)(奇怪的 LINQ 异常(索引越界))