CsvHelper没有向内存流写任何东西

时间:2012-11-30 13:20:34

标签: c# csvhelper

我有以下方法:

public byte[] WriteCsvWithHeaderToMemory<T>(IEnumerable<T> records) where T : class
{
    using (var memoryStream = new MemoryStream())
    using (var streamWriter = new StreamWriter(memoryStream))
    using (var csvWriter = new CsvWriter(streamWriter))
    {
        csvWriter.WriteRecords<T>(records);

        return memoryStream.ToArray();
    }
}

使用对象列表调用哪个 - 最终来自数据库,但由于某些东西不起作用,我只是填充静态集合。传递的对象如下:

using CsvHelper.Configuration;

namespace Application.Models.ViewModels
{
    public class Model
    {
        [CsvField(Name = "Field 1", Ignore = false)]
        public string Field1 { get; set; }

        [CsvField(Name = "Statistic 1", Ignore = false)]
        public int Stat1{ get; set; }

        [CsvField(Name = "Statistic 2", Ignore = false)]
        public int Stat2{ get; set; }

        [CsvField(Name = "Statistic 3", Ignore = false)]
        public int Stat3{ get; set; }

        [CsvField(Name = "Statistic 4", Ignore = false)]
        public int Stat4{ get; set; }
    }
}

我要做的是将一个集合写入csv以便在MVC应用程序中下载。每次我尝试写入方法时,MemoryStream都会返回零长度并且没有传递给它。我以前用过这个,但由于某种原因它只是不起作用 - 我有点困惑。谁能指出我在这里做错了什么?

干杯

5 个答案:

答案 0 :(得分:32)

你已经拥有了using块,非常棒。那将为你冲洗你的作家。您可以稍微更改代码,以使其正常工作。

using (var memoryStream = new MemoryStream())
{
    using (var streamWriter = new StreamWriter(memoryStream))
    using (var csvWriter = new CsvWriter(streamWriter))
    {
        csvWriter.WriteRecords<T>(records);
    } // StreamWriter gets flushed here.

    return memoryStream.ToArray();
}

如果您打开AutoFlush,则需要小心。这将在每次写入后刷新。如果您的流是网络流并通过网络传输,那将非常慢。

答案 1 :(得分:21)

在返回刷新writer / stream之前放置csvWriter.Flush();

编辑:Per Jack的回复。它应该是刷新的流,而不是csvWriter。 streamWriter.Flush();。留下原始解决方案,但添加此更正。

答案 2 :(得分:9)

csvWriter中没有刷新,刷新是在streamWriter中。什么时候叫

  

csvWriter.Dispose();

它将刷新流。 另一种方法是设置

  

streamWriter.AutoFlush = true;

每次都会自动刷新流。

答案 3 :(得分:7)

将所有这些放在一起(以及更正的注释),包括重置内存流位置,对我来说最终的解决方案是;

        using (MemoryStream ms = new MemoryStream())
        {
            using (TextWriter tw = new StreamWriter(ms))
            using (CsvWriter csv = new CsvWriter(tw))
            {
                csv.WriteRecords(errors); // Converts error records to CSV

                tw.Flush(); // flush the buffered text to stream
                ms.Seek(0, SeekOrigin.Begin); // reset stream position

                Attachment a = new Attachment(ms, "errors.csv"); // Create attachment from the stream
                // I sent an email here with the csv attached.
            }
        }

如果帮助别人!

答案 4 :(得分:4)

以下是工作示例:

void Main()
{
    var records = new List<dynamic>{
       new { Id = 1, Name = "one" },
       new { Id = 2, Name = "two" },
    };

    Console.WriteLine(records.ToCsv());
}

public static class Extensions {
    public static string ToCsv<T>(this IEnumerable<T> collection)
    {
        using (var memoryStream = new MemoryStream())
        {
            using (var streamWriter = new StreamWriter(memoryStream))
            using (var csvWriter = new CsvWriter(streamWriter))
            {
                csvWriter.WriteRecords(collection);
            } // StreamWriter gets flushed here.

            return Encoding.ASCII.GetString(memoryStream.ToArray());
        }
    }
}

基于this回答。