Generating a zipOutputstream from a folder having other .zip files in it - c#

I am trying to convert an entire azure blob storage folder and its contents to a zip file .Inside this folder ,I have different types of files eg, .txt,.mp3,.zip files .But once the folder is converted to zip file I noticed that all the .zip file types got corrupted,.How can I prevent my zip files from corrupted. I am using Ionic.Zip library to generate zip files
Here is the code I am using .Here I am able to generate and download the zip file successfully with all other filetypes except the inner zip files.
var allFiles = directory.ListBlobs(new BlobRequestOptions { UseFlatBlobListing = true }).Where(x => x.GetType() == typeof(CloudBlockBlob)).Cast<CloudBlob>();
string xyzblob = directory.Uri.ToString().TrimEnd('/');
var dBlob = blobClient.GetBlobReference(xyzblob);
byte[] fileBytes = null;
fileBytes = dBlob.DownloadByteArray();
foreach (var file in allFiles)
{
using (var fileStream = new MemoryStream(fileBytes))
{
var entryName = file.Uri.ToString().Replace(directory.Uri.ToString(), "");
zipOutputStream.PutNextEntry(entryName);
fileStream.Seek(0, SeekOrigin.Begin);
int count = fileStream.Read(fileBytes, 0, fileBytes.Length);
while (count > 0)
{
zipOutputStream.Write(fileBytes, 0, count);
count = fileStream.Read(fileBytes, 0, fileBytes.Length);
if (!Response.IsClientConnected)
{
break;
}
Response.Flush();
}
fileStream.Close();
}
}
zipOutputStream.Close();
More details
I am downloading a folder ,."myFolder" and its contents from azure blob as a zip file eg, myfolders.zip.
Here is how the file structure inside "myFolder" /azure blob
MyFolder/mymusic/ test.mp3
MyFolder/mytext/ newtext.txt
MyFolder/MyZipfiles/ myzip.zip
My code I posted above will generate a zip all the contents of the folder to create "MyFolder.zip" and will download automatically .Now if you unzip "MyFolder.zip" file , due to some reason , the myzip.zip is getting corrupted.If I try to open myzip.zip file ,its showing a message "windows cannot open the folder ,the compressed zipped folder "myzip.zip" is invalid"
Please help me find a solution so that the .zip files wont get corrupted
I tried to download to stream ,but same results.,The inner zip files are getting corrupted.all other file types are in good shape.
zipOutputStream.PutNextEntry(entryName);
destBlob.DownloadToStream(zipOutputStream);

I am assuming you already tried downloading one of those zip files and opening it, right?
If that is the case, one thing I would suggest is to eliminate the intermediate fileBytes array completely. Using fileBytes as the buffer to fileStream and then reading from fileStream to fileBytes might be the culprit. On the other hand, you start from offset 0 and write to the beginning of fileBytes anyway, so it might be working just fine.
In any case, a more efficient solution is; you can call PutNextEntry and then call the blob object's DownloadToStream method by passing in the zip stream itself. That would simply copy the entire blob directly into the zip stream without having to manage an intermediate buffer.

When it starts to pick the .zip file ,I added BlobReference to .zip file and this resolved the issue
dBlob = blobClient.GetBlobReference(entryName.EndsWith(".zip") ? file.Uri.ToString() : xyzblob);
zipOutputStream.PutNextEntry(entryName);
dBlob.DownloadToStream(zipOutputStream);

Related

How can i download just my pdf file an not the full file path and folders

So I finally got this to work and download my pdf files into a zip file. See below:
List<string> manypaths = (List<string>)TempData["temp"];
var startpath = manypaths;
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");
}
So the manypaths list variable is holding onto a few paths to the pdf file which are like \\\\ost-stji01\pdfstorage\deposit\02_29_2019.pdf
So when the user downloads these files they have to click through multiple folder structure i.e ost0ji01 > pdfstorage > desposit > then they get to their file.
My question is how can i download just the files and not the entire folder structure. SO when they open the zip file its all of the files and they don't have to go through 3 or 4 folder directories.
If you want to flatten the paths in your ZIP file, use this.
zip.AddFiles(manypaths, #"\");
The second parameter of AddFiles allows you to specify the path of your files in the archive and \ is the root in your archive. Therefore, all files will be located directly in your archive without subfolders.

C# - Extracting contents of compressed file without saving

I have a compressed file (.osz) stored on an S3 Bucket which contains a .os file which I need to read the contents of.
I need to be able to extract/decompress and read the contents of the compressed file without downloading the file directly to the PC due to security reasons.
I am able to retrieve the compressed file (.osz) using the URL address of it's S3 Bucket path. Then using ZipArchive I am able to access the files contained within the compressed file. I am then able to extract the file I require by using the 'ExtractToFile' function as seen below. However, this function extracts the file (.os) and saves it locally in the path specified.
WebClient client = new WebClient();
byte[] bytes = client.DownloadData(OSZFilepath); // Read the .osz file contents into a byte array
using (MemoryStream zipStream = new MemoryStream(bytes))
{
// Create the zip containing the file from the stream
ZipArchive zip = new ZipArchive(zipStream);
// extract the compressed file and download the .os file contained within
var fileName = Guid.NewGuid().ToString() + ".OS";
var baseDirectory = Environment.ExpandEnvironmentVariables(System.Web.Configuration.WebConfigurationManager.AppSettings["DataStorage"].ToString());
zip.Entries[0].ExtractToFile(Path.Combine(baseDirectory, "ProjectFiles", fileName));
Although this extracted file can be successfully read and imported by my program, I cannot use this method as I am not able to save the file onto the user's computer due to security restrictions and program requirements.
Therefore I need to programmatically extract/decompress the file I need in order to read the contents and programmatically import it into my program.
I have tried to use the following code to do this:
ZipArchiveEntry entry = zip.GetEntry(zip.Entries[0].Name);
Stream stream = entry.Open();
StreamReader reader = new StreamReader(stream);
string contents = reader.ReadToEnd();
However the resulting contents throws up an error when I try to import it, indicating that the contents is different to the contents of the file that gets saved using 'ExtractToFile'.
This is confirmed when I save this contents as a seperate file and compare it to the file saved using 'ExtractToFile'. The 'ExtractToFile' file is bigger than the latter.
So my question is: is there another way to successfully decompress/extract a compressed file and obtain the contents without using the 'ExtractToFile' method and having to save the extracted file somewhere?
Thanks for your help.

The magic number in GZip header is not correct. Make sure you are passing in a GZip stream.(.exe file)

I want to extract a exe file. The exe file contain some files and folders. When I try to extract the file using winrar it gets extracted but when I am trying to extract the exe file using some examples I am getting this error:
The magic number in GZip header is not correct. Make sure you are passing in a GZip stream.
I have used some samples and googled a lot for my problem but didn't get my answer, and I have used some libraries also.
I used this code but same error:
public static void Decompress(FileInfo fi)
{
// Get the stream of the source file.
using (FileStream inFile = fi.OpenRead())
{
// Get original file extension, for example
// "doc" from report.doc.gz.
string curFile = fi.FullName;
string origName = curFile.Remove(curFile.Length -
fi.Extension.Length);
//Create the decompressed file.
using (FileStream outFile = File.Create(origName))
{
using (GZipStream Decompress = new GZipStream(inFile,
CompressionMode.Decompress))
{
// Copy the decompression stream
// into the output file.
Decompress.CopyTo(outFile);
Console.WriteLine("Decompressed: {0}", fi.Name);
}
}
}
}
That's because the .exe file is a self-extracting archive...
You should give DotNetZip a try. From the project's FAQ:
Does this library read self-extracting zip files?
Yes. DotNetZip can read self-extracting archives (SFX) generated by WinZip, and WinZip
can read SFX files generated by DotNetZip.
You can install it from Nuget easily.

Unzipping A Gzip File That Contains Folders In C#

I've got a windows program using C# that is working with log files. Some of these different log files come in gzipped (for instance test.log.gz). I've got code using SharpZipLib to unzip those log files and it works really well.
public static void unZip(string gzipFilePath, string targetDir)
{
byte[] dataBuffer = new byte[4096];
using (System.IO.Stream fs = new FileStream(gzipFilePath, FileMode.Open, FileAccess.Read))
{
using (GZipInputStream gzipStream = new GZipInputStream(fs))
{
string fnOut = Path.Combine(targetDir, Path.GetFileNameWithoutExtension(gzipFilePath));
using (FileStream fsOut = File.Create(fnOut))
{
StreamUtils.Copy(gzipStream, fsOut, dataBuffer);
}
}
}
}
From my research, it would seem that gzip files are typically one file, so it's always for instance, test.htm.gz. So I would create a file named test.htm and put the uncompressed information into test.htm, which happens in this part of the code:
using (GZipInputStream gzipStream = new GZipInputStream(fs))
{
string fnOut = Path.Combine(targetDir, Path.GetFileNameWithoutExtension(gzipFilePath));
using (FileStream fsOut = File.Create(fnOut))
{
StreamUtils.Copy(gzipStream, fsOut, dataBuffer);
}
}
This is all well and good but the problem I'm having is I've been given a log file, for example again, test.log.gz that has directories zipped into it.
When I use the 7-Zip gui to unzip the file, the log file I need is five directories deep in folders. So after unzipping with 7-zip, it outputs:
folder1 -> folder2 -> folder3 -> folder4 -> folder5 -> test.log
Trying to use the method provided from SharpLib only gives me a small subset of the data of the file in test.log.
I haven't been able to find any code or issues dealing with gzipped files containing folders and from what I can tell, you're not supposed to do that. It should be in a .tar and then gzipped.
Any one have any idea of what I could do with this .gz file?
First Maybe try using another lib here are a few
http://dotnetzip.codeplex.com/
http://www.icsharpcode.net/OpenSource/SharpZipLib/
There is also a built in GZ lib built into .net see
Unzipping a .gz file using C#
There is still just one file in there, so there isn't any violation of the gzip format. gzip permits an entire path name to be stored with the file, so that path may simply be ghostcache/ic_split_files/CBN/00-christmas/test.log and 7-Zip is faithfully recreating that path. You should be able to see this in the gzip header, starting about ten bytes in.
The fact that you are getting back only a subset of the log may or may not be related to the pathname in the gzip file.
Please provide a hex dump of the first 64 bytes of the .gz file that worked and the the .gz file that didn't.

Upload zip file error

I am using Uploadify to upload multiple files in my ASP.NET MVC application. In the controller action, I need to check if one of the uploaded files is a zip file, and if yes, I need to check its contents. For the zip functionality I am using the ICSharpCode.SharpZipLib.
When uploading a zip file from say my desktop, I am getting the following error:
Could not find file 'C:\Program Files (x86)\Common Files\Microsoft Shared\DevServer\10.0\xyz.zip' on the following line of code:
FileStream fs = System.IO.File.OpenRead(Path.GetFullPath(fileData.FileName));
ZipFile zf = new ZipFile(fs);
How do I get past this error?
[HttpPost]
public ActionResult Upload(HttpPostedFileBase fileData)
{
if (fileData != null && fileData.ContentLength > 0)
{
if (Path.GetExtension(fileData.FileName) == ".zip")
{
FileStream fs = System.IO.File.OpenRead(Path.GetFullPath(fileData.FileName));
ZipFile zf = new ZipFile(fs);
foreach (ZipEntry zipEntry in zf)
{
}
}
else
{
var fileName = Server.MapPath("~/Content/uploads/" + Path.GetFileName(fileData.FileName));
fileData.SaveAs(fileName);
return Json(true);
}
}
return Json(false);
}
HttpPostedFileBase.FileName is the name of the file uploaded, not the location on the file stored on the server. HttpPostedFileBase does not store the file on the server, only as a stream. Your options are either open the stream in memory (if your 3rd party utilies allow for opening streams) or saving the file to a known location, then open it from that location.
Path.GetFullPath gets a full path from the current directory.
That has nothing to do with your HttpUploadedFileBase, which isn't on disk.
You need to pass a stream instead of a file path.
If you want to check if it is a zip file, you could always look at the content-type coming back.
application/zip
This might work for what you are trying to do. Also, just try and look at what the content-type, you might find something more specific to your needs.

Categories

Resources