|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Announcements
Chapters
Services
Feature Zones
|
IntroductionThis article shortly explains some classes that give you the possibility to modify an archive without completely extracting it. The way I solved it is not really beautiful, but it works. I used a mix of the existing C# wrapper code for zlib (together with minizip) and some of my own code. A better way would be writing a wrapper class for libzip. And probably, the best way would be enhancing SharpZipLib so that it can modify archives. So feel free to work on that ;-). Also note that these classes do not support enhanced settings like compression levels or archive comments because I didn't need them. But you could easily add these features. BackgroundEveryone who needs compression/decompression for C# most probably would use the SharpZipLib from IC#Code. I also did that. Until now. I have been using that library for compressing the data my program generates. Fortunately, the output was all of the same type, so I was able to save it in the same file. But now I have different types of data that belong to different parts of the program, so splitting up the data into files would be a good way to achieve this. I wanted to modify this archive in memory, because it is rather ugly to completely extract it. I've been searching around for a while, and I only found an old C# wrapper class from Gerry Shaws. I knew that SharpZipLib is no solution for me, so I downloaded it and tried to get it working. There were some bugs in it that caused some weird behaviour which vanished after I replaced all the unsafe parts with normal C# code (you have to now, Gerry's code is a little bit weird ;). And well, besides that, I adjusted the code heavily to my needs. I replaced his rather hard to handle Using the codeI have made modifying of the archives (hopefully) very simple. You just need to instantiate an // Don't forget to add this two lines
using System.IO;
using OrganicBit.Zip;
ZipArchive Archive = new ZipArchive("test.zip", FileAccess.ReadWrite);
byte[] Data = new byte[Archive["test.txt"].Length];
Archive["test.txt"].Read(Data,0,Data.Length);
Console.WriteLine("Contents of 'test.txt'\n"+
System.Text.Encoding.Default.GetString(Data));
Console.WriteLine("Contents of the new file:");
Data = System.Text.Encoding.Default.GetBytes(Console.ReadLine());
Archive["test.txt"].Write(Data,0,Data.Length);
Archive.Close();
Notice that even if test.zip does not exist, you have to open it with To see what is in an archive, you can simply enumerate your instance: // Besides the Name, a ZipEntry
// instance also offers lots of other information
foreach(ZipEntry entry in Archive)
Console.WriteLine(entry.Name);
You can also check whether a file exists, or delete some: if(Archive.Contains("test.txt"))
Console.WriteLine("File test.txt is there");
// Archive.Delete() deletes the whole archive
// when it doesn't contain any other files
bool success = Archive.DeleteFile("test.txt");
if(success)
Console.WriteLine("File has been deleted");
else Console.WriteLine("File is not in archive");
Limitations
Points of interestThe unlovely part of zlib together with minizip is the fact that you can't open an archive for reading and writing simultaneously. I hid that fact in my classes, and exposed only the Credits...go to the following people:
History
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||