diff --git a/docs/articles/core/binary/datastream.md b/docs/articles/core/binary/datastream.md index 55525a66..a55ac1db 100644 --- a/docs/articles/core/binary/datastream.md +++ b/docs/articles/core/binary/datastream.md @@ -94,6 +94,8 @@ internally maps to the .NET enumerations `FileMode` and `FileAccess` as follow: > hundreds of `DataStream` on different files ready without running out of > resources in the operative system. + + > [!TIP] > `FileOpenMode` is handy enumeration that covers most use cases. If you require > any other combination of `FileMode` and `FileAccess` you can create the @@ -119,7 +121,9 @@ applies to the content that targets this `DataStream`, not the entire parent > [!NOTE] > The method ignores the current position, it will always start writing from the -> start to the end. It will **restore** the current position after comparing. +> start to the end. It will **restore** the current position after writing. It +> will also start **truncate** the output file. It will not append or preserve +> any existing content. The path should point to the output file. If there is any directory that doesn't exist, it will create them first. diff --git a/src/Yarhl.UnitTests/IO/DataStreamTests.cs b/src/Yarhl.UnitTests/IO/DataStreamTests.cs index d619cb79..e93f214c 100644 --- a/src/Yarhl.UnitTests/IO/DataStreamTests.cs +++ b/src/Yarhl.UnitTests/IO/DataStreamTests.cs @@ -1368,17 +1368,44 @@ public void WriteToWhenLengthZeroCreatesEmptyFile() { string tempFile = Path.Combine( Path.GetTempPath(), - Path.GetRandomFileName(), Path.GetRandomFileName()); - DataStream stream = new DataStream(); - stream.WriteTo(tempFile); + try { + var stream = new DataStream(); + stream.WriteTo(tempFile); - Assert.That(File.Exists(tempFile), Is.True); - FileStream fs = new FileStream(tempFile, FileMode.Open, FileAccess.Read); - Assert.AreEqual(0, fs.Length); - fs.Dispose(); - File.Delete(tempFile); + Assert.That(File.Exists(tempFile), Is.True); + + using var fs = new FileStream(tempFile, FileMode.Open, FileAccess.Read); + Assert.That(fs.Length, Is.EqualTo(0)); + } finally { + File.Delete(tempFile); + } + } + + [Test] + public void WriteToWhenTruncatesExistingFile() + { + string tempFile = Path.Combine( + Path.GetTempPath(), + Path.GetRandomFileName()); + + byte[] expected = new byte[] { 0xCA, 0xFE }; + using var stream = new DataStream(); + stream.Write(expected); + + try { + // Pre-fill the output file with some long content + File.WriteAllText(tempFile, "hello world!"); + + // Overwrite with 2 bytes stream content + stream.WriteTo(tempFile); + + byte[] actual = File.ReadAllBytes(tempFile); + Assert.That(actual, Is.EquivalentTo(expected)); + } finally { + File.Delete(tempFile); + } } [Test] diff --git a/src/Yarhl/IO/DataStream.cs b/src/Yarhl/IO/DataStream.cs index 4ce701eb..b57dccd6 100644 --- a/src/Yarhl/IO/DataStream.cs +++ b/src/Yarhl/IO/DataStream.cs @@ -616,7 +616,7 @@ public void WriteSegmentTo(long start, long length, string fileOut) } // We use FileStream so it creates a file even when the length is zero - using var segment = new FileStream(fileOut, FileMode.OpenOrCreate, FileAccess.Write); + using var segment = new FileStream(fileOut, FileMode.Create, FileAccess.Write); WriteSegmentTo(start, length, segment); }