0

I'm trying to unzip a zip file which is splitted to 5 parts. Problem is each part is in a different CD and i need to be able to change disks while unzipping. I have used Ionic.Zip to do that with no luck!

foreach (var entry in zip.Entries)
    {
        var stream = entry.OpenReader();
        var buffer = new byte[readByte];
        int n;
        try
        {
            while ((n = stream.Read(buffer, 0, buffer.Length)) > 0)
            {
               fileStream.Write(buffer, 0, buffer.Length);
            }
        }
        catch (FileNotFoundException ex)
        {
            // stream is closed and you cant continue           
            MessageBox.Show("Change CD");

            while ((n = stream.Read(buffer,0, buffer.Length)) > 0)
            {
                fileStream.Write(buffer, 0, buffer.Length);
            }
        }
    }

I have tried SevenZip, ZipSharp but i just cant implement it! Is there any way to handle this situation?

Milad Hosseinpanahi
  • 1,495
  • 12
  • 20

1 Answers1

2

To open a splitted ZipArchive no extra Library is needed, but some extra work needs to be done

List<string> files = new List<string> { "zip.001",
                                        "zip.002",
                                        "zip.003",
                                        "zip.004",
                                        };
using (var zipFile = new ZipArchive(new CombinationStream(files.Select(x => new FileStream(x, FileMode.Open) as Stream).ToList()), ZipArchiveMode.Read)) 
{
    // Do whatever you want
}

In this Example i use CombinationStream to open all zipfiles, but you can easily write your own class inheriting Stream for your needs which waits for all CDs to be read.

A startingpoint could be (just pseudocode):

public class MultiDeviceStream : Stream
{
    [...]
    private Queue<Stream> streams;
    private Stream activeStream;

    public byte ReadByte() {
        byte result;
        if (!activeStream.EndOfStream) {
            result = activeStream.ReadByte();
            if (!streams.CanDequeue && activeStream.EndOfStream) {
                // raise some event signaling to change the CD and wait for the new filestream here
                this.EndOfStream = true;
            }
        } else {
            if (streams.CanDequeue) {
                activeStream = streams.Dequeue();
            }
            else
            {
                throw EndOfStreamException();
            }
            return ReadByte();
        }
        return result;
    }
}
Sebastian L
  • 838
  • 9
  • 29