是否有内置方法将多个文件作为一个流处理?

我有一个文件列表,我需要按特定顺序将它们读入给定大小的byte []。 这对于单个文件本身不是问题,简单的((got = fs.Read(piece,0,pieceLength))> 0)完成工作完全正常。 文件的最后一段可能比期望的要小,这很好。

现在,有一个棘手的问题:如果我有多个文件,我需要有一个连续的流,这意味着如果文件的最后一块比pieceLength小,那么我需要读取(pieceLength-got)的下一个文件,然后继续,直到最后一个文件的结尾。

基本上,给定X文件,我将始终读取完全是pieceLength long的部分,除了最后一个文件的最后一部分,它可能更小。

我只是想知道是否已经在.net(3.5 SP1)中构建了一些function。 我目前的方法是创建一个接受文件列表然后公开Read(byte[] buffer, long index, long length)函数的类,类似于FileStream.Read()。 这应该是非常直接的,因为我不必更改我的读取数据的调用代码,但在重新发明轮子之前,我只想仔细检查轮子是否已经内置到BCL中。

谢谢 :)

我不相信框架中有任何内容,但我建议让它更灵活一点 – 在构造函数中使用IEnumerable ,并自己派生自Stream 。 然后,你可以得到文件流(假设C#3.0):

 Stream combined = new CombinationStream(files.Select(file => File.Open(file)); 

“所有权”部分在这里有点棘手 – 上面将允许组合流获取其读取的任何流的所有权,但您可能不希望它必须遍历所有其余流并将它们全部关闭如果它是过早关闭。

这是我根据@jon双向飞碟的想法提出的。

它只是实现了Read,这对我来说已经足够了。 (但是我没有需要帮助来实现BeginRead / EndRead方法。)以下是包含sync和async的完整代码 – Read和BeginRead / EndRead

https://github.com/facebook-csharp-sdk/combination-stream/blob/master/src/CombinationStream-Net20/CombinationStream.cs

 internal class CombinationStream : System.IO.Stream { private readonly System.Collections.Generic.IList _streams; private int _currentStreamIndex; private System.IO.Stream _currentStream; private long _length = -1; private long _postion; public CombinationStream(System.Collections.Generic.IList streams) { if (streams == null) { throw new System.ArgumentNullException("streams"); } _streams = streams; if (streams.Count > 0) { _currentStream = streams[_currentStreamIndex++]; } } public override void Flush() { if (_currentStream != null) { _currentStream.Flush(); } } public override long Seek(long offset, System.IO.SeekOrigin origin) { throw new System.InvalidOperationException("Stream is not seekable."); } public override void SetLength(long value) { this._length = value; } public override int Read(byte[] buffer, int offset, int count) { int result = 0; int buffPostion = offset; while (count > 0) { int bytesRead = _currentStream.Read(buffer, buffPostion, count); result += bytesRead; buffPostion += bytesRead; _postion += bytesRead; if (bytesRead <= count) { count -= bytesRead; } if (count > 0) { if (_currentStreamIndex >= _streams.Count) { break; } _currentStream = _streams[_currentStreamIndex++]; } } return result; } public override long Length { get { if (_length == -1) { _length = 0; foreach (var stream in _streams) { _length += stream.Length; } } return _length; } } public override long Position { get { return this._postion; } set { throw new System.NotImplementedException(); } } public override void Write(byte[] buffer, int offset, int count) { throw new System.InvalidOperationException("Stream is not writable"); } public override bool CanRead { get { return true; } } public override bool CanSeek { get { return false; } } public override bool CanWrite { get { return false; } } } 

也可作为NuGet包提供

 Install-Package CombinationStream