diff --git a/OpenMcdf.Tests/StorageTests.cs b/OpenMcdf.Tests/StorageTests.cs index addf75f..c617d59 100644 --- a/OpenMcdf.Tests/StorageTests.cs +++ b/OpenMcdf.Tests/StorageTests.cs @@ -277,16 +277,13 @@ public void DeleteStream(Version version) [TestMethod] [DataRow(Version.V3)] [DataRow(Version.V4)] - public void Consolidate(Version version) + public void ConsolidateMemoryStream(Version version) { byte[] buffer = new byte[4096]; - string fileName = Path.GetTempFileName(); - - try + using MemoryStream memoryStream = new(); + using (var rootStorage = RootStorage.Create(memoryStream, version, StorageModeFlags.LeaveOpen)) { - using MemoryStream memoryStream = new(); - using var rootStorage = RootStorage.Create(memoryStream, version, StorageModeFlags.LeaveOpen); using (CfbStream stream = rootStorage.CreateStream("Test")) stream.Write(buffer, 0, buffer.Length); @@ -302,6 +299,48 @@ public void Consolidate(Version version) Assert.IsTrue(originalMemoryStreamLength > memoryStream.Length); } + + using (var rootStorage = RootStorage.Create(memoryStream, version, StorageModeFlags.LeaveOpen)) + { + Assert.AreEqual(0, rootStorage.EnumerateEntries().Count()); + } + } + + [TestMethod] + [DataRow(Version.V3)] + [DataRow(Version.V4)] + public void ConsolidateFile(Version version) + { + byte[] buffer = new byte[4096]; + + string fileName = Path.GetTempFileName(); + + try + { + using (var rootStorage = RootStorage.Create(fileName, version)) + { + using (CfbStream stream = rootStorage.CreateStream("Test")) + stream.Write(buffer, 0, buffer.Length); + + Assert.AreEqual(1, rootStorage.EnumerateEntries().Count()); + + rootStorage.Flush(true); + + long originalLength = new FileInfo(fileName).Length; + + rootStorage.Delete("Test"); + + rootStorage.Flush(true); + + long consolidatedLength = new FileInfo(fileName).Length; + Assert.IsTrue(originalLength > consolidatedLength); + } + + using (var rootStorage = RootStorage.OpenRead(fileName)) + { + Assert.AreEqual(0, rootStorage.EnumerateEntries().Count()); + } + } finally { File.Delete(fileName); diff --git a/OpenMcdf/RootContext.cs b/OpenMcdf/RootContext.cs index d263e65..e9508cf 100644 --- a/OpenMcdf/RootContext.cs +++ b/OpenMcdf/RootContext.cs @@ -188,6 +188,12 @@ public void ExtendStreamLength(long length) isDirty = true; } + public void Consolidate(long length) + { + BaseStream.SetLength(length); + Length = length; + } + public void WriteHeader() { CfbBinaryWriter writer = Writer; diff --git a/OpenMcdf/RootStorage.cs b/OpenMcdf/RootStorage.cs index 60970af..15229be 100644 --- a/OpenMcdf/RootStorage.cs +++ b/OpenMcdf/RootStorage.cs @@ -165,23 +165,26 @@ void Consolidate() else throw new NotSupportedException("Unsupported stream type for consolidation."); - using (RootStorage destinationStorage = Create(destinationStream, Context.Version, storageModeFlags)) + using (RootStorage destinationStorage = Create(destinationStream, Context.Version, storageModeFlags | StorageModeFlags.LeaveOpen)) CopyTo(destinationStorage); Context.BaseStream.Position = 0; destinationStream.Position = 0; destinationStream.CopyTo(Context.BaseStream); - Context.BaseStream.SetLength(destinationStream.Length); + Context.Consolidate(destinationStream.Length); } catch { + destinationStream?.Dispose(); + if (destinationStream is FileStream fs) { string fileName = fs.Name; - fs.Dispose(); File.Delete(fileName); } + + throw; } }