public void DisposeView() { SparseMemoryStream memStream = new SparseMemoryStream(new SparseMemoryBuffer(1), FileAccess.ReadWrite); memStream.SetLength(1024); ThreadSafeStream tss = new ThreadSafeStream(memStream); SparseStream altView = tss.OpenView(); altView.Dispose(); tss.ReadByte(); SparseStream altView2 = tss.OpenView(); altView2.ReadByte(); }
public void Dispose_StopsView() { SparseMemoryStream memStream = new SparseMemoryStream(new SparseMemoryBuffer(1), FileAccess.ReadWrite); memStream.SetLength(1024); ThreadSafeStream tss = new ThreadSafeStream(memStream); SparseStream altView = tss.OpenView(); tss.Dispose(); try { altView.ReadByte(); Assert.True(false, "Disposed stream didn't stop view"); } catch (ObjectDisposedException) { } }
private void RunSparse() { SparseStream inStream = InputStream as SparseStream; if (inStream == null) { inStream = SparseStream.FromStream(InputStream, Ownership.None); } if (BufferSize > SparseChunkSize && BufferSize % SparseChunkSize != 0) { throw new InvalidOperationException("Buffer size is not a multiple of the sparse chunk size"); } byte[] copyBuffer = new byte[Math.Max(BufferSize, SparseChunkSize)]; BytesRead = 0; BytesWritten = 0; foreach (StreamExtent extent in inStream.Extents) { inStream.Position = extent.Start; long extentOffset = 0; while (extentOffset < extent.Length) { int numRead = (int)Math.Min(copyBuffer.Length, extent.Length - extentOffset); bool readSuccess = ReadExact(inStream, copyBuffer, 0, numRead); if (!readSuccess) { break; //if we wasn't able to read this extent we should go to the next one } BytesRead += numRead; int copyBufferOffset = 0; for (int i = 0; i < numRead; i += SparseChunkSize) { if (IsAllZeros(copyBuffer, i, Math.Min(SparseChunkSize, numRead - i))) { if (copyBufferOffset < i) { OutputStream.Position = extent.Start + extentOffset + copyBufferOffset; OutputStream.Write(copyBuffer, copyBufferOffset, i - copyBufferOffset); BytesWritten += i - copyBufferOffset; } copyBufferOffset = i + SparseChunkSize; } } if (copyBufferOffset < numRead) { OutputStream.Position = extent.Start + extentOffset + copyBufferOffset; OutputStream.Write(copyBuffer, copyBufferOffset, numRead - copyBufferOffset); BytesWritten += numRead - copyBufferOffset; } extentOffset += numRead; RaiseProgressEvent(); } } // Ensure the output stream is at least as long as the input stream. This uses // read/write, rather than SetLength, to avoid failing on streams that can't be // explicitly resized. Side-effect of this, is that if outStream is an NTFS // file stream, then actual clusters will be allocated out to at least the // length of the input stream. if (OutputStream.Length < inStream.Length) { inStream.Position = inStream.Length - 1; int b = inStream.ReadByte(); if (b >= 0) { OutputStream.Position = inStream.Length - 1; OutputStream.WriteByte((byte)b); } } }