I am using DotNetZip to add a file from a MemoryStream to a zip file and then to save that zip as a MemoryStream so that I can email it as an attachment. The code below does not err but the MemoryStream must not be done right because it is unreadable. When I save the zip to my hard drive everything works perfect, just not when I try to save it to a stream.
using (ZipFile zip = new ZipFile())
{
var memStream = new MemoryStream();
var streamWriter = new StreamWriter(memStream);
streamWriter.WriteLine(stringContent);
streamWriter.Flush();
memStream.Seek(0, SeekOrigin.Begin);
ZipEntry e = zip.AddEntry("test.txt", memStream);
e.Password = "123456!";
e.Encryption = EncryptionAlgorithm.WinZipAes256;
var ms = new MemoryStream();
ms.Seek(0, SeekOrigin.Begin);
zip.Save(ms);
//ms is what I want to use to send as an attachment in an email
}
Ok, I figured out my problem, pretty stupid actually. Thanks for everyone's help!
ZipEntry e = zip.AddEntry("test.txt", memStream);
e.Password = "123456!";
e.Encryption = EncryptionAlgorithm.WinZipAes256;
//zip.Save("C:\\Test\\Test.zip");
//Stream outStream;
var ms = new MemoryStream();
zip.Save(ms);
//--Needed to add the following 2 lines to make it work----
ms.Seek(0, SeekOrigin.Begin);
ms.Flush();
I've copied your code, and then saved your final memory steam to disk as data.txt. It was completely unreadable to me, but then I realized that it wasn't a text file, it was a zip file, so i saved it as data.zip and it worked as expected
the method I used to save ms to disk is the following(immediately after your zip.Save(ms); line)
ms.Position = 0;
byte[] data = ms.ToArray();
File.WriteAllBytes("data.zip", data);
So, I believe that your memory stream is what It is supposed to be, which is compressed text. It won't be readable until you decompress it.
Related
I have generated a pdf using PDFSharp.
I call the save method, and save it to disk, and the file is perfect.
I then need to get the file into a MemorySteam, in preparion of sending it to my website to download. However, the file ends up invalid. corrupt.
So, to see where it's going wrong, I have put the file into a MemoryStream, and then I try write that steam to a file, to confirm all is OK. It isn't.
Here I sav the file to disk, to check it (debugging), and then put it into a stream:
document.Save("c:\\temp\\ggg.pdf");
MemoryStream ms = new MemoryStream();
document.Save(ms, false);
byte[] buffer = new byte[ms.Length];
ms.Seek(0, SeekOrigin.Begin);
ms.Flush();
ms.Read(buffer, 0, (int)ms.Length);
return ms;
I then return 'ms' to my calling function, and attempt to write the stream to a file:
var doc = GeneratePdf(1);
using (FileStream file = new FileStream("c:\\temp\\222.pdf", FileMode.Create, System.IO.FileAccess.Write))
{
byte[] bytes = new byte[doc.Length];
doc.Read(bytes, 0, (int)doc.Length);
file.Write(bytes, 0, bytes.Length);
doc.Close();
}
But 222.pdf is not a valid pdf. ggg.pdf was fine. So I am doing something wrong when I write to stream, and write to disk. Why is the file getting corrupted?
I cannot reproduce your issue (PdfSharp 1.32.3057.0). It seems to me that you are messing too much with manual stream copying.
Try the following code, which correctly creates a pdf, streams it into a MemoryStream and than saves it into a file:
var pdf = new PdfSharp.Pdf.PdfDocument();
var page = pdf.AddPage();
var gfx = XGraphics.FromPdfPage(page);
var font = new XFont("Verdana", 20, XFontStyle.BoldItalic);
gfx.DrawString("Hello, World!", font, XBrushes.Black, new XRect(0, 0, page.Width, page.Height), XStringFormats.Center);
var ms = new MemoryStream();
pdf.Save(ms, false);
ms.Position = 0;
using (var file = File.OpenWrite("test.pdf"))
ms.CopyTo(file); // no need for manual stream copy or buffers
DropboxClient dbx = new DropboxClient("************************");
var file = "/Excel/FileName.xlsx";
byte[] bytes = null;
FileStream fs = new FileStream("C:\\Users\\Admin\\Desktop\\Test.xlsx", FileMode.Open, FileAccess.Read);
BinaryReader br = new BinaryReader(fs);
long numBytes = fs.Length;
bytes = br.ReadBytes((int)numBytes);
var mem = new MemoryStream(Encoding.UTF8.GetBytes(bytes.ToString()));
var updated = await dbx.Files.UploadAsync(file, WriteMode.Overwrite.Instance, body: mem);
Here is the code, it overwrite the existing file as per need but make that file corrupted.
I think you're thinking too complex here. UploadAsync expects a Stream. MemoryStream is indeed a Stream, but so is FileStream. Getting rid of the extra reader will result in:
var source = "C:\\Users\\Admin\\Desktop\\Test.xlsx";
var target = "/Excel/FileName.xlsx";
using(var dbx = new DropboxClient("***"))
using(var fs = new FileStream(source, FileMode.Open, FileAccess.Read))
{
var updated = await dbx.Files.UploadAsync(
target, WriteMode.Overwrite.Instance, body: fs);
}
The reason the file will get corrupt is because of reading the data incorrectly. bytes.ToString() will result in System.Byte[]. You're actually uploading System.Byte[] literally instead of the file's contents, which is not a valid Excel document. Also converting a binary file into UTF-8 text doesn't work as expected, because it alters the content being uploaded.
I am testing some code. I am stuck with the following. What ever I write as text, the length of the zipped stream is always 10? What am I doing wrong?
var inStream = new MemoryStream();
var inWriter = new StreamWriter(inStream);
str text = "HelloWorldsasdfghj123455667880fgsjfhdfasdferrbvbyjun hbwecwcxqsz edcrgvebrjnuj5juerqwetsrgfggshurhtnbvzkfjhguhgrgal;kjhao;rhl;zkfhg;aorihghg;oahrgarhguhh';aaeaeiaijeihjrhfidfhfidfidhh953453453";
inWriter.WriteLine(text);
inWriter.Flush();
inStream.Position = 0;
var outStream = new MemoryStream();
var compressStream = new GZipStream(outStream, CompressionMode.Compress);
inStream.CopyTo(compressStream);
compressStream.Flush();
outStream.Flush();
compressStream.Flush();
outStream.Position = 0;
Console.WriteLine(outStream.Position);
Console.WriteLine(outStream.Length);
Until you Close it the compression stream doesn't know you've finished writing to it - so cannot complete its compression algorithm. Flushing flushes those parts it can flush, but until its been told you have completed adding new bytes it cannot flush its last package of compressed data.
I Have one 'System.Net.Mail.Attachment[] attachment' object , This object contains PDF,Xls,Doc or jpg file.
I want to save this attachment object to cloud server.
string sSavePath = "EmailAttachment/" + intSomeid + "/";
string strErrorMsg = string.Empty;
if ((attachments != null))
{
MemoryStream memoryStream = new MemoryStream();
StreamWriter memoryWriter = new StreamWriter(memoryStream);
memoryWriter.Write(attachments[0]);
memoryStream.Position = 0;
CloudFileSystem.SaveFileToCloudSystem(memoryStream, ref strErrorMsg, sSavePath, ConfigHelper.PrivateContainer, attachments[intI].Name);
memoryWriter.Dispose();
memoryStream.Dispose();
}
I have used the above code to save the file.
The File is saved to cloud but having 0 Byte data (Corrupted) File.
I have searched many places for that.
But not able to find error in the code.
Please suggest some solution in this case ?
Looks like you are making it yourself more difficult then needed. The Attachment instance has an ContentStream property which you don't need to feed through a MemoryStream at all.
string sSavePath = "EmailAttachment/" + intSomeid + "/";
string strErrorMsg = string.Empty;
if ((attachments != null))
{
CloudFileSystem.SaveFileToCloudSystem(
attachments[intI].ContentStream,
ref strErrorMsg,
sSavePath,
ConfigHelper.PrivateContainer,
attachments[intI].Name);
}
If you are doing this:
MemoryStream memoryStream = new MemoryStream();
StreamWriter memoryWriter = new StreamWriter(memoryStream);
memoryWriter.Write(attachments[0]);
You are probably writing the string representation of Attachment (ToString() gets called) and that is not the content of your file.
After so much r&d ,I have come up with the following answer
Memory stream of attachment object didn't work for me.
So I have approached temp path where the attachement was saved and do the following magical code :
string FileName = ((System.IO.FileStream (attachments[intI].ContentStream)).Name;
MemoryStream ms = new MemoryStream();
using (FileStream file = new FileStream(FileName, FileMode.Open, FileAccess.Read))
{
byte[] bytes = new byte[file.Length];
file.Read(bytes, 0, (int)file.Length);
ms.Write(bytes, 0, (int)file.Length);
}
ms.Position = 0;
CloudFileSystem.SaveFileToCloudSystem(ms, ref strErrorMsg, sSavePath, ConfigHelper.PrivateContainer, attachments[intI].Name);
ms.Dispose();
I hope my question and answer helps you for your project
I want to save a PdfSharp.Pdf.PdfDocument by its Save method to a Stream, but it doesn't attach the PDF header settings to it. So when I read back the Stream and return it to the user, he see that the PDF file is invalid. Is there a solution to attach the PDF header settings when PDFsharp saves to memory?
If you think there is an issue with PdfDocument.Save, then please report this on the PDFsharp forum (but please be more specific with your error description).
Your "solution" looks like a hack to me.
"pdfRenderer.Save" calls "PdfDocument.Save" internally.
Whatever the problem is - your "solution" still calls the same Save routine.
Edit:
To get a byte[] containing a PDF file, you only have to call:
MemoryStream stream = new MemoryStream();
document.Save(stream, false);
byte[] bytes = stream.ToArray();
Early versions of PDFsharp do not reset the stream position.
So you have to call
ms.Seek(0, SeekOrigin.Begin);
to reset the stream position before reading from the stream; this is no longer required for current versions.
Using ToArray can often be used instead of reading from the stream.
Edit 2: instead of stream.ToArray() it may be more efficient to use stream.GetBuffer(), but this buffer is usually larger than the PDF file and you only have to use stream.Length bytes from that buffer. Very useful for method that take a byte[] along with a length parameter.
So the solution:
MigraDoc.DocumentObjectModel.Document doc = new MigraDoc.DocumentObjectModel.Document();
MigraDoc.Rendering.DocumentRenderer renderer = new DocumentRenderer(doc);
MigraDoc.Rendering.PdfDocumentRenderer pdfRenderer = new MigraDoc.Rendering.PdfDocumentRenderer();
pdfRenderer.PdfDocument = pDoc;
pdfRenderer.DocumentRenderer = renderer;
using (MemoryStream ms = new MemoryStream())
{
pdfRenderer.Save(ms, false);
byte[] buffer = new byte[ms.Length];
ms.Seek(0, SeekOrigin.Begin);
ms.Flush();
ms.Read(buffer, 0, (int)ms.Length);
}
There is this MigraDoc stuff which comes with PdfSharp, but i hardly found any proper doc/faq for it. After hours of googling i've found a snippet which was something like this. Now it works.
I found simpler solution:
byte[] fileContents = null;
using(MemoryStream stream = new MemoryStream())
{
pdfDoc.Save(stream, true);
fileContents = stream.ToArray();
}
Source:
http://usefulaspandcsharp.wordpress.com/2010/03/09/save-a-pdf-to-a-byte-array-using-pdf-sharpmigradoc/
For MigraDoc (ver 1.30) I could save it with
PdfDocumentRenderer renderer = new PdfDocumentRenderer(true, PdfSharp.Pdf.PdfFontEmbedding.Always);
renderer.Document = report.m_Document;
renderer.RenderDocument();
using (MemoryStream stream = new MemoryStream())
{
renderer.PdfDocument.Save(stream, false);
... your code in here
}
Thanks Misnyo Solution. But for me it works like this:
Document document = new Document();
PdfDocumentRenderer pdfRenderer = new PdfDocumentRenderer();
//Add to document here.......
//render the document with pdf renderer
pdfRenderer.Document = document;
pdfRenderer.RenderDocument();
//Save renderer result into stream
using(MemoryStream ms = new MemoryStream())
{
pdfRenderer.PdfDocument.Save(ms, false);
byte[] buffer = new byte[ms.Length];
ms.Seek(0, SeekOrigin.Begin);
ms.Flush();
ms.Read(buffer, 0, (int)ms.Length);
ms.Position = 0;
}