/// <summary> Construct from a read-only file. </summary> /// <remarks> /// Used when recovering files written by a previous program /// instance from their locations. /// </remarks> public BlockFile(IFileMemory file, uint fileId) { _pinner = new Pinner(); _file = file ?? throw new ArgumentNullException(nameof(file)); FileId = fileId; _flags = new AppendList <ReadFlag>(); var offset = 0L; while (offset < _file.Length) { var block = AtOffset(offset); ref var header = ref block.Header; if (header.Rank != _flags.Count || header.ContentLength < 0 || header.ContentLength + BlockHeader.Size > _file.Length) { // The header of the block appears broken. Do not include // it in the list, and stop scanning (since we don't know // how far to jump ahead). break; } var thisOffset = offset; _flags.Append(ReadFlag.Triggered(() => VerifyAtOffset(thisOffset))); offset += block.RelativeOffsetToNextBlock; }
/// <summary> Construct from raw building blocks. </summary> /// <remarks> /// Used to create a read-only view over a file that is being written to. /// Note that <see cref="_flags"/> may grow over time, as new blocks are /// appended. /// </remarks> internal BlockFile( IFileMemory file, AppendList <ReadFlag> flags, uint fileId) { _file = file ?? throw new ArgumentNullException(nameof(file)); _flags = flags ?? throw new ArgumentNullException(nameof(flags)); FileId = fileId; }
private FileWriter(IFileMemory file, AppendList <ReadFlag> flags, uint fileId) { _file = file; _flags = flags; FileId = fileId; }