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)
            {
            }
        }
Example #3
0
        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);
                }
            }
        }