/// <summary> /// Прочитать метаданные страницы. /// </summary> /// <param name="stream">Поток.</param> private void ReadDataPageMetadata(Stream stream) { ReadHeader(); // если LowerOffset больше чем размер заголовка, то значит есть данные на странице. if (_header.LowerOffset > DataPageHeader.Size) { // читаем локальные индексы. ReadDataPageLocalIndexes(stream); } void ReadHeader() { var buffer = new byte[DataPageHeader.Size]; stream.Seek(0, SeekOrigin.Begin); stream.Read(buffer, 0, DataPageHeader.Size); var spanBuffer = buffer.AsSpan(); _header = new DataPageHeader { LowerOffset = spanBuffer.DecodeInt(0, out var nextStartOffset), UpperOffset = spanBuffer.DecodeInt(nextStartOffset, out _) }; } }
/// <summary> /// Единый метод для инициализации страницы. /// </summary> /// <param name="isCompleted">Является ли страница завершенной?</param> private void Initialize(bool isCompleted) { var fileInfo = new FileInfo(_fileName); if (!Directory.Exists(_fileName)) { Directory.CreateDirectory(Path.GetDirectoryName(_fileName)); } var fileStream = new FileStream( _fileName, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite, _config.BufferSize, FileOptions.SequentialScan ); // Если файл не найден, или файл есть, но он не завершенный if (!fileInfo.Exists || !isCompleted) { // если длина оказалась больше 0, значит файл уже существует и инициализирован. if (fileStream.Length > 0) { ReadDataPageMetadata(fileStream); } else { // файл новый, поэтому заполняем нулями. fileStream.SetLength(_config.PageSize); _header = new DataPageHeader { // для нового файла нижняя граница - после заголовка LowerOffset = DataPageHeader.Size, // а верхняя - конец файла. UpperOffset = (int)fileStream.Length }; } _bufferedFileWriter = new BufferedFileWriter( fileStream, _config.BufferSize, _config.AutoFlushInterval ); // записать заголовок в файл. UpdateHeader(); } else { // если файл существует и завершен, то читаем только метаданные. ReadDataPageMetadata(fileStream); } // Выключаем индексацию файла операционной системой, так как в файле массив байт, искать по контенту не получится :) fileInfo.Attributes = FileAttributes.NotContentIndexed; }