diff --git a/LiteDB/Engine/Disk/DiskService.cs b/LiteDB/Engine/Disk/DiskService.cs index 7c78d893b..ad2bc8344 100644 --- a/LiteDB/Engine/Disk/DiskService.cs +++ b/LiteDB/Engine/Disk/DiskService.cs @@ -40,7 +40,7 @@ public DiskService(EngineSettings settings, int[] memorySegmentSizes) _dataPool = new StreamPool(_dataFactory, false); _logPool = new StreamPool(_logFactory, true); - var isNew = !_dataFactory.Exists() || _dataFactory.GetLength() == 0L; + var isNew = _dataFactory.GetLength() == 0L; // create lazy async writer queue for log file _queue = new Lazy(() => new DiskWriterQueue(_logPool.Writer)); diff --git a/LiteDB/Engine/Disk/StreamFactory/FileStreamFactory.cs b/LiteDB/Engine/Disk/StreamFactory/FileStreamFactory.cs index 95e769a7a..169843ca4 100644 --- a/LiteDB/Engine/Disk/StreamFactory/FileStreamFactory.cs +++ b/LiteDB/Engine/Disk/StreamFactory/FileStreamFactory.cs @@ -40,7 +40,8 @@ public Stream GetStream(bool canWrite, bool sequencial) var isNewFile = write && this.Exists() == false; - var stream = new FileStream(_filename, + var stream = new FileStream( + _filename, _readonly ? System.IO.FileMode.Open : System.IO.FileMode.OpenOrCreate, write ? FileAccess.ReadWrite : FileAccess.Read, write ? FileShare.Read : FileShare.ReadWrite, @@ -56,7 +57,7 @@ public Stream GetStream(bool canWrite, bool sequencial) } /// - /// Get file length using FileInfo + /// Get file length using FileInfo. Crop file length if not length % PAGE_SIZE /// public long GetLength() { @@ -66,13 +67,29 @@ public long GetLength() // get physical file length from OS var length = new FileInfo(_filename).Length; - // if length < PAGE_SIZE, ignore file length (should be 0) - if (length < PAGE_SIZE) return 0; - - ENSURE(length % PAGE_SIZE == 0, $"file length must be PAGE_SIZE module. length={length}, file={Path.GetFileName(_filename)}"); + // if file length are not PAGE_SIZE module, maybe last save are not completed saved on disk + // crop file removing last uncompleted page saved + if (length % PAGE_SIZE != 0) + { + length = length - (length % PAGE_SIZE); + + using (var fs = new FileStream( + _filename, + System.IO.FileMode.Open, + FileAccess.Write, + FileShare.None, + PAGE_SIZE, + FileOptions.SequentialScan)) + { + fs.SetLength(length); + fs.FlushToDisk(); + } + } - // if encrypted must remove salt first page - return length - (_password == null ? 0 : PAGE_SIZE); + // if encrypted must remove salt first page (only if page contains data) + return length > 0 ? + length - (_password == null ? 0 : PAGE_SIZE) : + 0; } ///