Old topic! Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.
I need to be able to zip and unzip files that are known to be named oddly, and my current method (SharpZipLib and a recursive zip/unzip wrapper) can't do it right. An example would be "aux.class" which is a reserved file name, so File won't write that. I've currently rigged a bit of a renaming system specifically for this file, but I dont like doing that sort of thing, it's just too messy and inefficient having to do special things for one file.
Next, I've noticed that even though the files now unzip and rezip, there is a difference between the original and the rezip. Currently, both the manually unzipped and the programmatically unzipped folders have the same size, but there is a difference of over 90KB between the original and the rezipped files, when done so programmatically. Any difference in zips is highly unacceptable since it's actually a JAR archive I'm messing with.
There is the possibility that I am missing something, so I'll give the benefit of the doubt and post my wrapper here:
Spoiler
using System;
using System.Collections;
using System.IO;
using ICSharpCode.SharpZipLib.Zip;
namespace PatchCraft.Classes
{
public static class ZipUtils
{
public static void ZipFiles(string inputFolderPath, string outputPathAndFile, string password)
{
string[] moddedFileNames = null;
bool fileNamesModded = false;
if (File.Exists(inputFolderPath + @"\changedFiles.zud"))
{
moddedFileNames = File.ReadAllLines(inputFolderPath + @"\changedFiles.zud");
File.Delete(inputFolderPath + @"\changedFiles.zud");
fileNamesModded = true;
}
ArrayList ar = GenerateFileList(inputFolderPath); // generate file list
//int TrimLength = (Directory.GetParent(inputFolderPath)).ToString().Length;
int TrimLength = inputFolderPath.Length;
// find number of chars to remove // from orginal file path
//TrimLength += 1; //remove ‘\’
FileStream ostream;
byte[] obuffer;
string outPath = inputFolderPath + @"\" + outputPathAndFile;
ZipOutputStream oZipStream = new ZipOutputStream(File.Create(outputPathAndFile)); // create zip stream
if (password != null && password != String.Empty)
oZipStream.Password = password;
oZipStream.SetLevel(9); // maximum compression
ZipEntry oZipEntry;
foreach (string Fil in ar) // for each file, generate a zipentry
{
string realFile = Fil;
oZipEntry = new ZipEntry(realFile.Remove(0, TrimLength));
oZipStream.PutNextEntry(oZipEntry);
if (!Fil.EndsWith(@"/")) // if a file ends with ‘/’ its a directory
{
ostream = File.OpenRead(Fil);
obuffer = new byte[ostream.Length];
ostream.Read(obuffer, 0, obuffer.Length);
oZipStream.Write(obuffer, 0, obuffer.Length);
ostream.Close();
ostream.Dispose();
}
oZipEntry = null;
}
oZipStream.Finish();
oZipStream.Close();
oZipStream.Dispose();
ar = null;
}
private static ArrayList GenerateFileList(string Dir)
{
ArrayList files = new ArrayList();
bool Empty = true;
foreach (string file in Directory.GetFiles(Dir)) // add each file in directory
{
files.Add(file);
Empty = false;
}
if (Empty)
{
if (Directory.GetDirectories(Dir).Length == 0)
// if directory is completely empty, add it
{
files.Add(Dir + @"/");
}
}
foreach (string dirs in Directory.GetDirectories(Dir)) // recursive
{
foreach (object obj in GenerateFileList(dirs))
{
files.Add(obj);
}
}
return files; // return file list
}
public static void UnZipFiles(string zipPathAndFile, string outputFolder, string password, bool deleteZipFile)
{
ZipInputStream s = new ZipInputStream(File.OpenRead(zipPathAndFile));
if (password != null && password != String.Empty)
s.Password = password;
ZipEntry theEntry;
string tmpEntry = String.Empty;
while ((theEntry = s.GetNextEntry()) != null)
{
string directoryName = outputFolder;
string fileName = Path.GetFileName(theEntry.Name);
// create directory
if (directoryName != "")
{
Directory.CreateDirectory(directoryName);
}
if (fileName != String.Empty)
{
if (theEntry.Name.IndexOf(".ini") < 0)
{
string fullPath = "";
if (!theEntry.Name.Contains("aux"))
{
fullPath = directoryName + "\\" + theEntry.Name;
}
else
{
fullPath = directoryName + "\\_" + theEntry.Name;
}
fullPath = fullPath.Replace("\\ ", "\\");
string fullDirPath = Path.GetDirectoryName(fullPath);
if (!Directory.Exists(fullDirPath)) Directory.CreateDirectory(fullDirPath);
FileStream streamWriter = null;
streamWriter = File.Create(fullPath);
int size = 2048;
byte[] data = new byte[2048];
while (true)
{
size = s.Read(data, 0, data.Length);
if (size > 0)
{
streamWriter.Write(data, 0, size);
}
else
{
break;
}
}
streamWriter.Close();
streamWriter.Dispose();
}
}
}
s.Close();
s.Dispose();
theEntry = null;
if (deleteZipFile)
File.Delete(zipPathAndFile);
}
}
}
If my code is correct, then I can't use SharpZipLib. I need something that can zip and unzip files accurately with no difference between the original and the rezip, no matter the file name, so I'm looking to use something else. Anyone have any ideas on what else to try?
UPDATE: I have switched over to DotNetZip and it does FAR better. The JAR (being Minecraft) actually runs now! The problem now is still that aux.class file. Now, when loading a map, the game will crash with "Incompatible magic value 0 in class file aux" or "ClassDefNotFound for aux" which obviously means it is corrupted somehow, but I just don't know what's going on with it. I have narrowed it down to the fact that done manually, the file will use 313 KB zipped, but after programmatical modification, the file will be only 8. 7-Zip strangely enough shows that each has the same unzipped file size...
Old topic! Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.