У меня действительно простой вопрос, но поиск решения занимает много времени. Все равно не нашел и решил написать сюда. Ниже приведен код для получения строки в формате CSV. Но проблема в том, что данные CSV сокращены до 1020 символов. Просто верхние 1020 символов отображаются только в переменной «csvString».
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();
}
}
У кого-нибудь из экспертов есть идеи о том, что не так с этим кодом? Как получить полный CSV с объектом «записи»? Я ценю ваш достойный ответ по этому поводу.
Попробуйте вызвать var csvString = Encoding.UTF8.GetString(mem.ToArray()); после закрытия MemoryStream.
Если вам нужна строка, почему бы не использовать StringWriter? Если вы хотите сохранить данные на диске, зачем использовать MemoryStream вместо FileStream?





Прежде чем пытаться считать результат из 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
}
Это работает. Спасибо, 7he3rain.
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());
С этим ответом связано несколько проблем: (а) mem.Position = 0 не требуется для получения содержимого с помощью mem.ToArray(). (б) Он не скомпилируется, потому что using требуются скобки для объявления переменной и блок для того, что должно произойти перед удалением объекта. (c) Любые объекты, реализующие IDisposable, следует по возможности помещать в блок using. Никогда не создавайте одноразовые предметы и не позволяйте им «висеть», не выбрасывая и не возвращая их.
@7he3rain Вы предлагаете использовать var mem = new MemoryStream(); неверный синтаксис, который не вызывает Dispose() на объекте MemoryStream? Вы подразумеваете, что единственный правильный синтаксис using — это using (var mem = new MemoryStream()) { ...code that uses the memory stream... }?
Сначала я подумал, что это может быть правильный синтаксис, но «бессмысленный», поскольку объект будет удален в том же операторе, что и создан. Но на самом деле он даже не компилируется. Однако using (var mem = new MemoryStream()); немедленно компилирует и удаляет объект, но также приводит к тому, что переменная mem сразу выходит за пределы области видимости, поэтому на следующей строке с new StreamWriter(mem) произойдет сбой.
using (var mem = new MemoryStream()); — неправильный синтаксис. Вам нужно использовать синтаксис C# using: using var mem = new MemoryStream();Хорошо, я потратил некоторое время на изучение этого вопроса, и синтаксис @ian-boyd ДЕЙСТВИТЕЛЬНО работает, но ТОЛЬКО в C# 8 и выше. Я все еще использую Visual Studio 2019, которая, видимо, еще не поддерживает этот синтаксис. Лично мне не нравится новый/добавленный синтаксис using, потому что он скрывает время жизни одноразового объекта и усложняет понимание кода. Определенно не помогает, когда вы пытаетесь объяснить кому-то здесь, почему их код не работает (особенно, если опубликованный исходный код НЕ использует новый синтаксис).
Вы звоните
mem.ToArray()до того, как закрылиcsvWriterили очистилиwriter... по какой причине вы делаете это там, а не после вызоваFlushAsync?