Пример #1
0
        /// <summary> Internal use to specify aligned IO when using NoBuffering file option </summary>
        protected FragmentedFile(IFactory <Stream> streamFactory, int blockSize, int growthRate, int cacheLimit, FileOptions options)
        {
            _useAlignedIo  = (options & NoBuffering) == NoBuffering;
            _streamCache   = new StreamCache(streamFactory, cacheLimit);
            _header        = new FileBlock(blockSize, _useAlignedIo);
            _syncFreeBlock = new object();
            try
            {
                long fallocated;
                bool canWrite;

                using (Stream s = _streamCache.Open(FileAccess.ReadWrite))
                {
                    canWrite = s.CanWrite;
                    if (!s.CanRead)
                    {
                        throw new InvalidOperationException("The stream does not support Read access.");
                    }

                    _header.Read(s, blockSize);

                    if ((_header.Flags & ~BlockFlags.HeaderFilter) != BlockFlags.HeaderFlags)
                    {
                        throw new InvalidDataException();
                    }

                    _nextFree = _header.NextBlockId;
                    SetBlockSize(_header.Length, out _blockSize, out _maskVersion, out _maskOffset);
                    if (blockSize != _blockSize)
                    {
                        throw new ArgumentOutOfRangeException("blockSize");
                    }
                    fallocated   = LastAllocated(s);
                    _reallocSize = growthRate * _blockSize;

                    if (canWrite)
                    {
                        s.Position          = 0;
                        _header.NextBlockId = long.MinValue;
                        _header.Write(s, FileBlock.HeaderSize);
                    }
                }

                if (canWrite)
                {
                    if ((_header.Flags & BlockFlags.ResizingFile) == BlockFlags.ResizingFile && _nextFree > 0)
                    {
                        ResizeFile(_nextFree, Math.Max(fallocated, _nextFree + _reallocSize));
                    }

                    if (_nextFree == long.MinValue)
                    {
                        _nextFree = RecoverFreeBlocks();
                    }
                }
            }
            catch
            {
                _streamCache.Dispose();
                throw;
            }
        }
 public CachedStream(StreamCache cache, Stream rawStream, FileAccess access, Mutex ownerHandle) : base(rawStream)
 {
     _cache       = cache;
     _ownerHandle = ownerHandle;
     _fileAccess  = access;
 }