I am trying to download a zip of pdf files without having to go through the full directory path
So when I am downloading the files the user will have to click through the entire path to get to the pdf. I want just the files to download without the entire path.
So I did this:
public ActionResult DownloadStatements(string[] years, string[] months, string[] radio, string[] emails, string acctNum)
{
List<string> manypaths = (List<string>)TempData["temp"];
using (Ionic.Zip.ZipFile zip = new Ionic.Zip.ZipFile())
{
zip.AddFiles(manypaths , #"\");
MemoryStream output = new MemoryStream();
zip.Save(output);
return File(output.ToArray(), "application/zip");
}
}
In the line zip.AddFiles(manypaths, #"\") I added the #"\" and that seemed to do the trick. But now at that line of code I am getting an error:
System.ArgumentException: 'An item with the same key has already been added.
None of the files are duplicates as I have checked that. I just don't understand what is going on?
I was thinking about maybe if I added a timestamp to it it might help but can't figure out the proper way to do this in dotnetzip library.
Related
Im trying to send a compressed file with an email.
So the step is :
1. Compressed the file that we want to.
2. Send the email in outlook, with the attachment from the compressed file.
My problem is when the application try to search for the compressed file, it wont find because my path didnt right.
Here's the code
using (ZipFile zip = new ZipFile())
{
//zip.UseUnicodeAsNecessary = true;
zip.AddDirectory(#"Y:\"+tglskrg+"\\Result");
zip.Save(#"C:\Users\Desktop\"+tglskrg+".zip");
}
string path = Path.Combine(Directory.GetCurrentDirectory(), tglskrg + ".zip");
//Send email code(which basicly work);
my problem is , the file is saved in desktop
the actual result is , when the apps try to search for the file, the apps look in the path directory which from the code i write, the path is in the Debug folder from the application.
Anyone can help ? or maybe where did i do wrong?
Thankyou
Maybe I am not understanding your question; but, if you want to refer to the desktop folder, use Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory).
For example, you are trying to save your zip file to the desktop,
change this:
zip.Save(#"C:\Users\Desktop\"+tglskrg+".zip");
to this:
zip.Save(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory), tglskrg + ".zip"));
I want to create a zip file from a folder that it around 1.5GB, and have that zip file be split into chunks of 100MB. I've found quite a few threads on this, but nothing has quite worked out for me.
First I tried System.IO.Compression, but found that it doesn't support splitting the zip files (please correct me if I'm wrong!).
Next I tried Ionic.zip, which looked super easy, but every set of files I create is corrupted in some way (for example, the following code that uses the fonts directory as a test directory creates a set of files that I can't then open or unzip as an archive with either winzip or winrar):
using (var zipFile = new Ionic.Zip.ZipFile(Encoding.UTF8))
{
zipFile.AddDirectory("c:\\windows\\fonts", directoryPathInArchive: string.Empty);
zipFile.MaxOutputSegmentSize = 100 * 1000000;
zipFile.Save("c:\\users\\me\\test.zip");
}
Finally, I've tried the 7z.dll and SharpCompress. Using the Command Line and the 7z.exe file, the following works perfectly:
7z.exe a "c:\users\me\test.zip" "c:\Windows\Fonts" -v100m
But the following code gives the error "Value does not fall within the expected range."
SevenZipCompressor.SetLibraryPath("c:\\program files\\7-zip\\7z.dll");
var compressor = new SevenZipCompressor();
compressor.CompressionMethod = CompressionMethod.Lzma2;
compressor.CustomParameters.Add("v", "100m");
compressor.CompressDirectory("c:\\windows\\fonts\\", "c:\\users\\me\\test.zip");
I've also tried the following (having tried to figure out how the command line switches work in SharpCompress) which does create a zip file, but doesn't split it up:
SevenZipCompressor.SetLibraryPath("c:\\program files\\7-zip\\7z.dll");
var compressor = new SevenZipCompressor();
compressor.CompressionMethod = CompressionMethod.Lzma2;
compressor.CustomParameters.Add("mt", "on");
compressor.CustomParameters.Add("0", "LZMA2:c=100m");
compressor.CompressDirectory("c:\\windows\\fonts\\", "c:\\users\\me\\test.zip");
Does anyone know why any of the above methods aren't working? Or are there any other ways that people have got working that I haven't tried yet?
Thanks!
I am not aware of a library that supports the PKZIP split zip file format.
It's an old question, but Ionic is working. Maybe a little bit tricky, but ok. My first version also creates a set of files that I can't then unzip. But after changing the order of commands, the output can be unzipped.
private static void CreateEncryptedZipFile(string filename, string to, FileInfo fi, string password)
{
using (var zipFile = new Ionic.Zip.ZipFile())
{
zipFile.Password = password;
zipFile.Encryption = Ionic.Zip.EncryptionAlgorithm.WinZipAes256;
zipFile.CompressionLevel = Ionic.Zlib.CompressionLevel.BestCompression;
zipFile.AddFile(filename, directoryPathInArchive: string.Empty);
zipFile.MaxOutputSegmentSize = 1024*1024*128;
zipFile.Save(to + ".zip");
}
createXMLInfo(fi, to);
}
I am trying to extract files from zip files using the DotNetZip library. I am able to extract files when it is a single .zip file. However, when I try to extract files from a multi volume zip file like Something.zip.0 or Something.zip.1, I get the following two exceptions:
-Exception thrown: 'Ionic.Zip.BadReadException' in Ionic.Zip.dll
-Exception thrown: 'Ionic.Zip.ZipException' in Ionic.Zip.dll
Is it possible for DotNetZip to read these type of files, or should I be looking into an alternative approach? I am working on Visual Studios using C#.
Here's a snippet of how I implement my zip file extraction.
using (Ionic.Zip.ZipFile zip = Ionic.Zip.ZipFile.Read(_pathToZip))
{
zip.CompressionLevel = Ionic.Zlib.CompressionLevel.BestSpeed;
foreach(Ionic.Zip.ZipEntry ze in zip)
{
string fileName = ze.FileName;
bool isThereItemToExtract = isThereMatch(fileName.ToLower(), _folderList, _fileList);
if (isThereItemToExtract)
{
string pathOfFileToExtract = (_destinationPath + "\\" + ze.FileName).Replace('/', '\\');
string pathInNewZipFile = goUpOneDirectoryRelative(ze.FileName);
ze.Extract(_destinationPath, Ionic.Zip.ExtractExistingFileAction.OverwriteSilently);
_newZip.AddItem(pathOfFileToExtract, pathInNewZipFile);
}
}
_newZip.Save();
}
Please refer the DotNetZipLibrary code examples:
using Ionic.Zip;
private void MyExtract(string zipToUnpack, string unpackDirectory)
{
using (ZipFile zip1 = ZipFile.Read(zipToUnpack))
{
// here, we extract every entry, but we could extract conditionally
// based on entry name, size, date, checkbox status, etc.
foreach (ZipEntry e in zip1)
{
e.Extract(unpackDirectory, ExtractExistingFileAction.OverwriteSilently);
}
}
}
This method should be able to extract either split and not split zip files.
Every zip entry will be extracted with its full path as specified in the zip archive, relative to the current unpackDirectory.
There's no need to check if zip entry exsists (isThereItemToExtract). Interating the zip entries with foreach should do the job.
To avoid collisions you need to check if file with same name as zipEntry exsists in the unpackDirectory, or use ExtractExistingFileAction.OverwriteSilently flag.
Is it possible for DotNetZip to read these type of files, or should I be looking into an alternative approach? I am working on Visual Studios using C#.
In my experience, this is the best library to deal with split zip files.
Im having some trouble with IonicZip corrupting the files im packing down with it. At first i thought it was because of the file names, but i have now discovered that this is not the case.
Heres the code i use to pack down things
using (ZipFile pack = new ZipFile())
{
pack.AddProgress += (s, eventArgs) =>
{
if (eventArgs.EventType == ZipProgressEventType.Adding_AfterAddEntry)
{
Regex pattern = new Regex("[(]|[)]|[']|[[]|[]]|[+]");
eventArgs.CurrentEntry.FileName = pattern.Replace(eventArgs.CurrentEntry.FileName, "");
}
};
pack.AddDirectory(defPackageCreationPath + "\\installfiles", "");
pack.Save(outputPath + "\\package.mpp");
}
I used Regex to remove the shown characters from the filenames of the files being packed, as i thought it was because of the filenames they got corrupted somehow. But it is not.
Heres an example. I can pack down this file without problems
[Forge]FurnitureModv2.9.2(FULL).zip
However! If i pack the same file down with a lot of other files, everything screws up..
Take a look at this screenshot of the source folder, where im taking the files from and packing them with the above code, and the extracted folder to the right:
Notice how the file sizes from the source directory doesn't match with what is extracted? Well take a look at the sizes again.. The filenames are not matching those of the source! The file i mentioned before [Forge]FurnitureModv2.9.2(FULL).zip, which is now called ForgeFurnitureModv2.9.2FULL.zip and has gone from 467KB down to 51KB, and if i try to open it, im being told it is corrupted.. But take a look at the TooMuchTNT v2.5.zip file.. This files size is 467KB as the other file was from source, and if i open this file up i get the contents that should have been in [Forge]FurnitureModv2.9.2(FULL).zip !
So all in all i have two problems:
being that the file names doesnt match their contents from source folder
some files gets corrupted, however if i pack a file that gets corrupted without any other file it works fine, and it does not get corrupted.
Can you assist ? Maybe im packing the files wrongly ?
From examples, I've got a pretty good grasp over how to extract a zip file.
In nearly every example, the method of identifying when a ZipEntry is a directory is as follows
string directoryName = Path.GetDirectoryName(theEntry.Name);
string fileName = Path.GetFileName(theEntry.Name);
if (directoryName.Length > 0)
Directory.CreateDirectory(Path.Combine(destinationDirectory, directoryName));
if (fileName != String.Empty)
{
//read data and write to file
}
Now is is fine and all (directory encountered, create it), directory is available when the file is extracted.
I can add files to a zip fine, but how do I add folders? I understand I'll be looping through the directories, adding the files encountered (and their ZipEntry.Name property is populated properly), but how do I add a ZipEntry to the archive and instruct the ZipOutputStream that it is a directory?
ZipFile.AddDirectory does what you want. Small sample code here.