Home > Software engineering >  C# MemoryStream csv file not writing
C# MemoryStream csv file not writing

Time:11-24

I'm writing something that will create a .csv file in memory and email it as an attachment. The code below successfully emails a .csv file, but it is empty. I'm sure I'm missing something simple...

        MemoryStream memoryStream = new MemoryStream();
        TextWriter tw = new StreamWriter(memoryStream);

        tw.WriteLine("test,hello");
        tw.WriteLine("1234,543");

        Attachment attachment = new Attachment(memoryStream, new ContentType("text/csv"));
        attachment.Name = "test.csv";

        var Smtp = new SmtpClient();
        Smtp.UseDefaultCredentials = false;
        var NetworkCredentials = new NetworkCredential() { UserName = "[email protected]", Password = "NO" };
        Smtp.Port = 587;
        Smtp.EnableSsl = true;
        Smtp.Host = "smtp.gmail.com";
        Smtp.Credentials = NetworkCredentials;

        MailMessage msg = new MailMessage();
        msg.From = new MailAddress("[email protected]");
        msg.To.Add("[email protected]");
        msg.Subject = "subject text";
        msg.Body = "Attached is a file.";
        msg.Attachments.Add(attachment);
        Smtp.Send(msg);

CodePudding user response:

The below lines:

    tw.WriteLine("test,hello");
    tw.WriteLine("1234,543");

give out an appearance like they have written the data to the MemoryStream, but at this point the data is still in the buffer. In order to actually write it, you need to flush the data out, which can be done by adding this line after the above code:

tw.Flush();

Another thing to take care of, is that once the data has been written to the MemoryStream, the current pointer of MemoryStream is at the end of data. So, to properly copy the data from MemoryStream into your Attachment object, reset the position of MemoryStream pointer to zero (0), so that it can copy the entire data from beginning. This line will do the job:

memoryStream.position = 0;

So, the initial part of your code snippet should look something like this:

MemoryStream memoryStream = new MemoryStream();
TextWriter tw = new StreamWriter(memoryStream);

tw.WriteLine("test,hello");
tw.WriteLine("1234,543");

tw.Flush();
memoryStream.position = 0;

//rest of your code

CodePudding user response:

I would highly recommend you to use the using-clause

using(var memStream = new MemoryStream(...))
{
    using(var textWriter = new TextWriter(memStream))
    {
        textWriter.WriteLine(...);
    }
}

it will flush and close the Streams automatically. It's way more easy and more "save" to use.

using-Statement Microsoft explanation

CodePudding user response:

I would add to JoeGER94s answer that you don't need to {} in current net versions if the following code is only one statement.

using(var memStream = new MemoryStream(...))
using(var textWriter = new TextWriter(memStream))  
textWriter.WriteLine(...);

For further informations lookup this question

  • Related