Pack files into one, to later programmatically unpack them

c#, packaging

Solution

Just use a BinaryWriter/Reader and your own format. Something like this:

using (var fs = File.Create(...))
using (var bw = new BinaryWriter(fs))
{
    foreach (var file in Directory.GetFiles(...))
    {
        bw.Write(true); // means that a file will follow
        bw.Write(Path.GetFileName(file));
        var data = File.ReadAllBytes(file);
        bw.Write(data.Length);
        bw.Write(data);
    }
    bw.Write(false); // means end of file
}

So basically you write a bool that means whether there is a next file, the name and contents of each file, one after the other. Reading is the exact opposite. BinaryWriter/Reader take care of everything (it knows how long each string and byte array is, you will read back exactly what you wrote).

What this solution lacks: not an industry standard (but quite simple), doesn't store any additional metadata (you can add creation time, etc.), doesn't use a checksum (you can add an SHA1 hash after the contents), doesn't use compression (you said you don't need it), doesn't handle big files well (the problematic part is that it reads an entire file into a byte array and writes that, should work pretty well under 100 MB), doesn't handle multi-level directory hierarchies (can be added of course).

EDIT: The BinaryR/W know about string lengths, but not about byte array lengths. I added a length field before the byte array so that it can be read back exactly as it was written.

Problem

Is it possible to take all files and folders in a directory and pack them into a single package file, so that I may transfer this package over network and then unpack all files and folders from the package? I tried looking into ZIP files with C#, because I'm aiming for the same idea, but the actual methods for it only comes with .NET 3.5 (I believe), I also want the program to be very lightweight, meaning I don't want external modules lying around that has to be taken with if I wish to unzip/unpack a single file. How can I accomplish this?

Original source