Search code examples
c#filememorystreamc#-ziparchive

Unexpected end of archive on a ZIP file in c#


I am trying to zip a text file and split it into chunks(byte[]) in the console application.

public List<byte[]> CreateChunks(string fileName, string txtFilePath)
    {
        long chunkSize = 100 * 1000;//100kb
        var fileChunks = new List<byte[]>();

        using (var memoryStream = new MemoryStream())
        {
            using (var zipArchive = new ZipArchive(memoryStream, ZipArchiveMode.Create, false))
            {
                zipArchive.CreateEntryFromFile($"{txtFilePath}", fileName, CompressionLevel.Optimal);

                memoryStream.Position = 0;

                var buffer = new byte[chunkSize];

                while (memoryStream.Read(buffer, 0, buffer.Length) > 0)
                {
                    fileChunks.Add(buffer);
                }
            }
        }
        return fileChunks;
    }

With those chunks, I am trying to create a zip file in an another application.

    public void JoinChunks(List<byte[]> fileChunks, string filePath)
    {
        var memory = new MemoryStream();
        using (var file = new FileStream(filePath + "\\temp.zip", FileMode.Create))
        {
            foreach (var item in fileChunks)
            {
                memory.Write(item, 0, item.Length);
            }
            memory.WriteTo(file);
            file.Close();
        }
    }

When viewing the created zip file, the error pops out and says Unexpected end of archive.

enter image description here

If I try to chunk a text file and join them back, then it's working fine. The problem is in ZIP. Any solutions are most welcome.


Solution

  • You need to close the archive before you do anything else with the data, so that the archive object can flush the remaining data and finalize the archive. Your code should look like this:

    using (var memoryStream = new MemoryStream())
    {
        using (var zipArchive = new ZipArchive(memoryStream, ZipArchiveMode.Create, false))
        {
            zipArchive.CreateEntryFromFile($"{txtFilePath}", fileName, CompressionLevel.Optimal);
        }
    
        memoryStream.Position = 0;
    
        var buffer = new byte[chunkSize];
    
        while (memoryStream.Read(buffer, 0, buffer.Length) > 0)
        {
            fileChunks.Add(buffer);
        }
    }
    

    I.e. move the non-archive-related code out of the using statement for the zipArchive object.