私は、仕事場でプロジェクト用に書いたロジックのコピーを一度投稿します。このバージョンの利点は、バッファリングされたデータのリンクリストで動作するため、読み込み時に大量のメモリをキャッシュしたり、メモリをコピーしたりする必要がないことです。さらに、そのスレッドセーフであり、ネットワークストリームのように動作します。利用可能なデータがないときに読み込むとき:データが利用可能になるかタイムアウトになるまで待ちます。また、x個のバイトを読み込み、y個のバイトしかない場合は、すべてのバイトを読み込んだ後に戻ります。私はこれが助けて欲しい!
public class SlidingStream : Stream
{
#region Other stream member implementations
...
#endregion Other stream member implementations
public SlidingStream()
{
ReadTimeout = -1;
}
private readonly object _writeSyncRoot = new object();
private readonly object _readSyncRoot = new object();
private readonly LinkedList<ArraySegment<byte>> _pendingSegments = new LinkedList<ArraySegment<byte>>();
private readonly ManualResetEventSlim _dataAvailableResetEvent = new ManualResetEventSlim();
public int ReadTimeout { get; set; }
public override int Read(byte[] buffer, int offset, int count)
{
if (_dataAvailableResetEvent.Wait(ReadTimeout))
throw new TimeoutException("No data available");
lock (_readSyncRoot)
{
int currentCount = 0;
int currentOffset = 0;
while (currentCount != count)
{
ArraySegment<byte> segment = _pendingSegments.First.Value;
_pendingSegments.RemoveFirst();
int index = segment.Offset;
for (; index < segment.Count; index++)
{
if (currentOffset < offset)
{
currentOffset++;
}
else
{
buffer[currentCount] = segment.Array[index];
currentCount++;
}
}
if (currentCount == count)
{
if (index < segment.Offset + segment.Count)
{
_pendingSegments.AddFirst(new ArraySegment<byte>(segment.Array, index, segment.Offset + segment.Count - index));
}
}
if (_pendingSegments.Count == 0)
{
_dataAvailableResetEvent.Reset();
return currentCount;
}
}
return currentCount;
}
}
public override void Write(byte[] buffer, int offset, int count)
{
lock (_writeSyncRoot)
{
byte[] copy = new byte[count];
Array.Copy(buffer, offset, copy, 0, count);
_pendingSegments.AddLast(new ArraySegment<byte>(copy));
_dataAvailableResetEvent.Set();
}
}
}
読み取りバッファ内で前後にジャンプすると何か問題はありますか? – Ryan
NetworkStreamスタイルの読み込み、読み込み、読み込みなどとは対照的に、私が言ったこととそれを追跡する必要があるだけです – Deanna
異なるサイズの配列を読み書きする必要がありますか? 'byte []'の待ち行列があなたにとって十分なものではないでしょうか? – svick