c# dotnetzip memorystream with zip file - c#

What I am trying to do in the code below is to open up a zip file from a memoryStream which has files within it that are created from memoryStream as well.
Note that I am using c# MVC as I have a return File...
memoryStream1 does have a length to it so not sure when I open up the archive.zip, it says
Excel cannot open payload.xlsx because the file format or file extenion is not valid.
Verify that the fle has not been corrupted and that the file extension matches
the format of the file.
The file extension is definitely xlsx so that can't be the problem. Am I going about this in the wrong way?
I have the following code:
var memoryStream1 = new MemoryStream();
gc.CreatePackage(memoryStream1);
var memoryStream = new MemoryStream();
using (var zip = new ZipFile())
{
zip.AddEntry("payload.xlsx", memoryStream1);
zip.Save(memoryStream);
}
memoryStream.Seek(0, 0);
return File(memoryStream, "application/octet-stream", "archive.zip");

Related

Is possible to create zip password protected file without first creating file, then zip it

I am writing data into text file and using below code,
await using var file = new StreamWriter(filePath);
foreach (var packet in resultPackets)
{
file.WriteLine(JsonConvert.SerializeObject(packet));
}
And I am using below code to zip the file with password protected using `DotNetZip,
using (ZipFile zip = new ZipFile())
{
zip.Password = "password";
zip.AddFile(filePath);
zip.Save(#"C:\tmp\data4.zip");
}
Is there a way to combined both, I want to create a file on the fly as password protected.
I don't
want to create first file with data, t
then create zip file from it
and delete the base file
Is this possible? Thanks!
Okay, so since this is still unanswered, here's a small program that does the job for me:
using (var stream = new MemoryStream())
using (var streamWriter = new StreamWriter(stream))
{
// Insert your code in here, i.e.
//foreach (var packet in resultPackets)
//{
// streamWriter.WriteLine(JsonConvert.SerializeObject(packet));
//}
// ... instead I write a simple string.
streamWriter.Write("Hello World!");
// Make sure the contents from the StreamWriter are actually flushed into the stream, then seek the beginning of the stream.
streamWriter.Flush();
stream.Seek(0, SeekOrigin.Begin);
using (ZipFile zip = new ZipFile())
{
zip.Password = "password";
// Write the contents of the stream into a file that is called "test.txt"
zip.AddEntry("test.txt", stream);
// Save the archive.
zip.Save("test.zip");
}
}
Note how AddEntry does not create any form of temporary file. Instead, when the archive is saved, the contents of the stream are read and put into a compressed file within the archive. However, be aware that the whole content of the file are completely kept in memory before it the archive is written to the disk.

It does not appear to be a valid archive (Byte array to zip file in c#.net)

I am facing issue while converting byte array to zip file.Even though zip file is created using the below code but when I am extracting the zip file I am getting error "Cannot open file. It does not appear to be a valid archive".
private static void ShowZipFile(string fileName, byte[] data)
{
byte[] compress = Compress(data);
File.WriteAllBytes(fileName, compress);
}
private static byte[] Compress(byte[] data)
{
using (MemoryStream memory = new MemoryStream())
{
using (GZipStream gzip = new GZipStream(memory,
CompressionMode.Compress, true))
{
gzip.Write(data, 0, data.Length);
}
return memory.ToArray();
}
}
A GZipStream isn't a zip file, basically - it's a gzip file. That's just compressed data, without any notions of multiple files, file names etc. If you save the file as foo.gz you may find that the zip tool you use knows how to decompress that, but you definitely need to understand that it's not the same as a foo.zip with file entries etc.
If you want to create an actual zip file, you might want to look at SharpZipLib, System.IO.Compression.ZipFile or similar libraries.

How to Convert Binary file data to a physical type with a given MIME Type

I have a database table (tbl_document) which contains details of files which were uploaded into it over time.
I want to write a console application to download these files to a given location.
The table has three pieces of information, which I should use:
The FileContents in varbinary format;
The MIME Type (contentType) for each file, in nvarchar format for example something like this:
application/x-zip-compressed
application/msword
application/vnd.openxmlformats-officedocument.wordprocessingml.document
application/pdf
application/pdf
In MVC, I would have done something like this to perform this task:
public FileContentResult DownloadFile()
{
FileContentResult result = new FileContentResult(file.FileContents, file.ContentType);
result.FileDownloadName = file.FileName;
return result;
}
I have tried other ways to do this such as this one:
WebClient myWebClient = new WebClient();
FileContentResult result = new FileContentResult(fileContents, contentType);
I couldn't really get to save the file using any of the above. Please could you help.
Many thanks.
I have actually solved it like this:
// fileContents is the binary file being downloaded; I didn't need to use the MIME Types
MemoryStream ms = new MemoryStream(fileContents);
//write to file
FileStream file = new FileStream(filePath, FileMode.Create, FileAccess.Write);
ms.WriteTo(file);
file.Close();
ms.Close();

Is it possible to change file content directly in zip file?

I have form with text box and customer wants to store all changes from this textbox to zip archive.
I am using http://dotnetzip.codeplex.com
and i have example of code:
using (ZipFile zip = new ZipFile())
{
zip.AddFile("text.txt");
zip.Save("Backup.zip");
}
And i dont want to create each time temp text.txt and zip it back.
Can I access text.txt as Stream inside zip file and save text there?
There is an example in DotNetZip that use a Stream with the method AddEntry.
String zipToCreate = "Content.zip";
String fileNameInArchive = "Content-From-Stream.bin";
using (System.IO.Stream streamToRead = MyStreamOpener())
{
using (ZipFile zip = new ZipFile())
{
ZipEntry entry= zip.AddEntry(fileNameInArchive, streamToRead);
zip.Save(zipToCreate); // the stream is read implicitly here
}
}
A little test using LinqPad shows that it is possible to use a MemoryStream to build the zip file
void Main()
{
UnicodeEncoding uniEncoding = new UnicodeEncoding();
byte[] firstString = uniEncoding.GetBytes("This is the current contents of your TextBox");
using(MemoryStream memStream = new MemoryStream(100))
{
memStream.Write(firstString, 0 , firstString.Length);
// Reposition the stream at the beginning (otherwise an empty file will be created in the zip archive
memStream.Seek(0, SeekOrigin.Begin);
using (ZipFile zip = new ZipFile())
{
ZipEntry entry= zip.AddEntry("TextBoxData.txt", memStream);
zip.Save(#"D:\temp\memzip.zip");
}
}
}
There is another DotNetZip method accepting a file path as an argument:
zip.RemoveEntry(entry);
zip.AddEntry(entry.FileName, text, ASCIIEncoding.Unicode);

iTextSharp + FileStream = Corrupt PDF file

I am trying to create a pdf file with iTextSharp. My attempt writes the content of the pdf to a MemoryStream so I can write the result both into file and a database BLOB. The file gets created, has a size of about 21kB and it looks like a pdf when opend with Notepad++. But my PDF viewer says it's currupted.
Here is a little code snippet (only tries to write to a file, not to a database):
Document myDocument = new Document();
MemoryStream myMemoryStream = new MemoryStream();
PdfWriter myPDFWriter = PdfWriter.GetInstance(myDocument, myMemoryStream);
myDocument.Open();
// Content of the pdf gets inserted here
using (FileStream fs = File.Create("D:\\...\\aTestFile.pdf"))
{
myMemoryStream.WriteTo(fs);
}
myMemoryStream.Close();
Where is the mistake I make?
Thank you,
Norbert
I think your problem was that you weren't properly adding content to your PDF. This is done through the Document.Add() method and you finish up by calling Document.Close().
When you call Document.Close() however, your MemoryStream also closes so you won't be able to write it to your FileStream as you have. You can get around this by storing the content of your MemoryStream to a byte array.
The following code snippet works for me:
using (MemoryStream myMemoryStream = new MemoryStream()) {
Document myDocument = new Document();
PdfWriter myPDFWriter = PdfWriter.GetInstance(myDocument, myMemoryStream);
myDocument.Open();
// Add to content to your PDF here...
myDocument.Add(new Paragraph("I hope this works for you."));
// We're done adding stuff to our PDF.
myDocument.Close();
byte[] content = myMemoryStream.ToArray();
// Write out PDF from memory stream.
using (FileStream fs = File.Create("aTestFile.pdf")) {
fs.Write(content, 0, (int)content.Length);
}
}
I had similar issue. My file gets downloaded but the file size will be 13Bytes. I resolved the issue when I used binary writer to write my file
byte[] bytes = new byte[0];
//pass in your API response into the bytes initialized
using (StreamWriter streamWriter = new StreamWriter(FilePath, true))
{
BinaryWriter binaryWriter = new BinaryWriter(streamWriter.BaseStream);
binaryWriter.Write(bytes);
}
Just some thoughts - what happens if you replace the memory stream with a file stream? Does this give you the result you need? This will at least tell you where the problem could be.
If this does work, how do the files differ (in size and binary representation)?
Just a guess, but have you tried seeking to the beginning of the memory stream before writing?
myMemoryStream.Seek(0, SeekOrigin.Begin);
Try double checking your code that manipulates the PDF with iText. Make sure you're calling the appropriate EndText method of any PdfContentByte objects, and make sure you call myDocument.Close() before writing the file to disk. Those are things I've had problems with in the past when generating PDFs with iTextSharp.
documentobject.Close();
using (FileStream fs = System.IO.File.Create(path)){
Memorystreamobject.WriteTo(fs);
}

Categories