MemoryStream brings half of data when generating a CSV string

81 Views Asked by At

I do have really a simple question, but takes a lot of times for finding out a solution. Still couldn't find and thought to post here. Below is the code for getting CSV formatted string. But the issue is, csv data truncated from 1020 characters. Simply top 1020 characters only show in "csvString" variable.

var records = new List<CSVDto>();
//In here Assign data to records 

var csvConfig = new CsvConfiguration(CultureInfo.InvariantCulture)
{
    HasHeaderRecord = true,
    Delimiter = ","
};

using (var mem = new MemoryStream())
{
    using (var writer = new StreamWriter(mem))
    {
        using (var csvWriter = new CsvWriter(writer, csvConfig))
        {
            await csvWriter.WriteRecordsAsync(records);
            var csvString = Encoding.UTF8.GetString(mem.ToArray()); //im getting only first 1020 characters.                              
        }
        await writer.FlushAsync();
    }
}

Any expert have an idea about what's going wrong with this code? How to get full csv with "records" object? I appreciate your worth reply on this.

2

There are 2 best solutions below

0
7he3rain On BEST ANSWER

You should first flush/close the writers before trying to read out the result from the MemoryStream.

using (var mem = new MemoryStream())
{
    using (var writer = new StreamWriter(mem))
    {
        using (var csvWriter = new CsvWriter(writer, csvConfig))
        {
            await csvWriter.WriteRecordsAsync(records);
        }
        await writer.FlushAsync(); // not actually needed, since closing the writer (end of using block) will also trigger flushing
    }
    var csvString = Encoding.UTF8.GetString(mem.ToArray()); // <- should contain all data now
}
5
Ian Boyd On
using var mem = new MemoryStream();
using var writer = new StreamWriter(mem);
using var csvWriter = new CsvWriter(writer, csvConfig);

await csvWriter.WriteRecordsAsync(records);

// Flush the CsvWriter and StreamWriter to ensure all data is written to the MemoryStream.
await csvWriter.FlushAsync();
await writer.FlushAsync();

// Go back to the beginning of the MemoryStream before reading it.
// NOTE: this is not required for .ToArray; but you get the idea.
// It is required if you were going to read from the MemoryStream as a stream. 
// So we include this line as a reminder to do the right thing.
// This is especially useful on SO if you're here to solve a problem
// relating to unflushed buffers - even though you're not using .ToArray.
// Also it's good practice to do it because 
// good programmers look both ways before crossing a one-way street.
mem.Position = 0;

var csvString = Encoding.UTF8.GetString(mem.ToArray());