Our app is running in Docker and we have limited memory available in each process. We work with and zip large files so it is customary to use FileStreams as temporary streams with the FileOptions.DeleteOnClose option.
When we create a zip file we create a temporary file stream, use ZipArchive to write to the stream, dispose the ZipArchive, rewind the stream, and copy the stream's contents to some persistent store like Mongo GridFS. The problem we are running into is that the zip file in the persistent store is an invalid zip file.
To isolate the issue we created a persistent 'temporary' file stream and checked it for validity after we dispose the ZipArchive and after we dispose the file stream. What we are seeing is that the filestream after the ZipArchive Dispose() is an INVALID zip file, but after the filestream Dispose() it is a VALID stream. After the filestream is disposed, the length on disk DOES NOT MATCH the length before it was disposed. Why is the file on disk not a valid zip file until the filestream is disposed?
[Test]
public async Task ZipFile2()
{
string zipPath = Path.Combine(Path.GetTempPath(), "test.zip");
long streamLengthBeforeClose;
using (var sourceFile = new FileStream("../../../../Foundations.Blob.UnitTests/TestData/test-file.txt", FileMode.Open))
using (var zipStream = new FileStream(zipPath, FileMode.Create))
{
using var archive = new ZipArchive(zipStream, ZipArchiveMode.Create, true);
{
var entry = archive.CreateEntry("test-file.txt");
using (var entryStream = entry.Open())
{
// copy from the blob to the zip entry
await sourceFile.CopyToAsync(entryStream, CancellationToken.None);
}
}
zipStream.Flush();
// at this point the zipStream IS NOT A VALID ZIP FILE
streamLengthBeforeClose = zipStream.Length;
}
// at this point the zipStream IS A VALID ZIP FILE
var fi = new FileInfo(zipPath);
// These do not match
Assert.AreEqual(streamLengthBeforeClose, fi.Length);
}
Note: we do not want to use persistent temporary file streams wrapped with a try/finally with a delete. Nor are memory streams viable solutions.