How to save attachments? - c#

I am using MailKit/MimeKit 1.2.7 (latest NuGet version).
I have been reading the API documentation and several posts on stackoverflow. But I still wasn't able to successfully save email attachments as a file.
Here is my current code:
var mimePart = (attachment as MimePart);
var memoryStream = new MemoryStream();
mimePart.ContentObject.DecodeTo(attachmentStream);
using (var fileStream = new FileStream(filePath, FileMode.Create, FileAccess.Write))
{
memoryStream.CopyTo(fileStream);
}
I have been trying this code with different kinds of attachments. The created file on my disc is always empty.
What am I missing?

The problem with the above code is that you are forgetting to reset the memoryStream.Position back to 0 :-)
However, a better way of doing what you want to do is this:
var mimePart = (attachment as MimePart);
using (var fileStream = new FileStream(filePath, FileMode.Create, FileAccess.Write))
{
mimePart.ContentObject.DecodeTo(fileStream);
}
In other words, there's no need to use a temporary memory stream.

Related

Saving MemoryStream to File produces 0 bytes

I'm using this code to write an MP3 MemoryStream to file:
using (var nSpeakStreamAsMp3 = new MemoryStream())
using (var nWavFileReader = new WaveFileReader(nSpeakStream))
using (var nMp3Writer = new LameMP3FileWriter(nSpeakStreamAsMp3, nWavFileReader.WaveFormat, LAMEPreset.STANDARD_FAST))
{
nWavFileReader.CopyTo(nMp3Writer);
string sPath = "C:\\inetpub\\wwwroot\\server\\bin\\mymp3.mp3";
using (FileStream nFile = new FileStream(sPath, FileMode.Create, System.IO.FileAccess.Write))
{
nSpeakStreamAsMp3.CopyTo(nFile);
}
sRet = (String.Concat("data:audio/mpeg;base64,", Convert.ToBase64String(nSpeakStreamAsMp3.ToArray())));
}
return sRet;
For some reason which I don't see, this produces a file of 0 bytes.
However, the MP3 stream is valid and does work. I'm passing it as a Base64String to a website, and I do hear it.
Where might be the error here?
nSpeakStreamAsMp3 is currently positioned at the end of the stream; you need to think like a VCR: be kind, rewind (nSpeakStreamAsMp3.Position = 0;) before you copy the value out again
make sure you flush nMp3Writer; if possible, close nMp3Writer completely

Deflatestream - end of stream reached before parsing was completed

I try to write a List to a FileStream. Since the object was too big, I split the list in evenly distributed chunks, and append it to the FileStream with a DeflateStream to compress the data. This all works fine.
However if I try to do the same to decompress it, it gives an error: 'reached the end of the stream before parsing was completed'. This is the code to decompress:
using (FileStream fs = new FileStream(filePath, FileMode.Open)) {
using (DeflateStream ds = new DeflateStream(fs, CompressionMode.Decompress, true)) {
//Deserialize offerte
BinaryFormatter bf = new BinaryFormatter();
//Check position
while (ds.BaseStream.Position < ds.BaseStream.Length) {
result.AddRange((List<User>)bf.Deserialize(ds));
}
}
}
What I notice is that the first chunk of users is nicely being written to result. However when it should start on the second chunk of users it gives an error right away (It seems before even trying to get the second chunk). What can I do about this or is wrong?
#Edit 10:43 - 16-10-2015 Additional remark
If I skip the DeflateStream and only use FileStream, then it works like a charm.
Compress method (I call this function x times, every chunk once):
using (FileStream fs = new FileStream(filePath, FileMode.Append)) {
using (DeflateStream cs = new DeflateStream(fs, CompressionMode.Compress)) {
//Serialize offerte
BinaryFormatter bf = new BinaryFormatter();
bf.Serialize(cs, offerte);
}
}

How to password protect pdf programmatically in .NET?

I need to programmatically protect a PDF file with a password in C#.
The same PDF file must be saved with different names and different password.
Does anyone know a method for this (no expensive tools, please..)?
It can be done using itextsharp:
using (var input = new FileStream("test.pdf", FileMode.Open, FileAccess.Read, FileShare.Read))
using (var output = new FileStream("test_encrypted.pdf", FileMode.Create, FileAccess.Write, FileShare.None))
{
var reader = new PdfReader(input);
PdfEncryptor.Encrypt(reader, output, true, "userPassword", "userPassword", PdfWriter.ALLOW_PRINTING);
}

Read a PDF into a string or byte[] and write that string/byte[] back to disk

I am having a problem in my app where it reads a PDF from disk, and then has to write it back to a different location later.
The emitted file is not a valid PDF anymore.
In very simplified form, I have tried reading/writing it using
var bytes = File.ReadAllBytes(#"c:\myfile.pdf");
File.WriteAllBytes(#"c:\output.pdf", bytes);
and
var input = new StreamReader(#"c:\myfile.pdf").ReadToEnd();
File.WriteAllText("c:\output.pdf", input);
... and about 100 permutations of the above with various encodings being specified. None of the output files were valid PDFs.
Can someone please lend a hand? Many thanks!!
In C#/.Net 4.0:
using (var i = new FileStream(#"input.pdf", FileMode.Open, FileAccess.Read))
using (var o = File.Create(#"output.pdf"))
i.CopyTo(o);
If you insist on having the byte[] first:
using (var i = new FileStream(#"input.pdf", FileMode.Open, FileAccess.Read))
using (var ms = new MemoryStream())
{
i.CopyTo(ms);
byte[] rawdata = ms.GetBuffer();
using (var o = File.Create(#"output.pdf"))
ms.CopyTo(o);
}
The memory stream may need to be ms.Seek(0, SeekOrigin.Origin) or something like that before the second CopyTo. look it up, or try it out
You're using File.WriteAllText to write your file out.
Try File.WriteAllBytes.

CRM File attachments

CRM saves attachements in AnnotationBase base table.
How can I convert the text in the DocumentBody entity back to file and save it the file system.
I’m comfortable with plugins and workflow activities. But can't figure how to convert a string in the database to a file on the system.
using(FileStream fs = new FileStream("fileName", FileMode.Create,
FileAccess.Write))
{
StreamWriter writer = new StreamWriter(fs);
writer.Write(yourString);
fs.Flush();
}
[EDIT]
If we're talking about BASE64 strings then try this:
using (FileStream fs = new FileStream("fileName", FileMode.Create,
FileAccess.Write))
{
byte[] bytes = Convert.FromBase64String(yourString);
fs.Write(bytes, 0, bytes.Length);
fs.Flush();
}
Grrr.
Look all day, then find the answer 5mins after posting the question.
File.WriteAllBytes("c:\\word1.docx", System.Convert.FromBase64String(str));

Categories

Resources