/// <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; }