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

Ian*_*ill 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();
    }
}
Run Code Online (Sandbox Code Playgroud)

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

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; }
    }
}
Run Code Online (Sandbox Code Playgroud)

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

干杯

Jos*_*ose 40

你已经拥有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();
}
Run Code Online (Sandbox Code Playgroud)

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

  • 我认为这是不正确的。如果这样做,StreamWriter 将被刷新,但它也会处理底层流。 (2认同)

Eli*_*ert 26

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

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

  • 这是一个错误的答案.CsvWriter上没有Flush方法. (11认同)
  • 我的首选答案是:http://stackoverflow.com/a/22997765/1795053让`using`语句为您做繁重的工作. (4认同)

Jos*_*osh 16

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

        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.
            }
        }
Run Code Online (Sandbox Code Playgroud)

如果帮助别人!

  • `ms.Seek(0, SeekOrigin.Begin);` 对我来说是缺失的部分。刷新,使用语句,在我重置流之前,这些都没有任何区别。 (2认同)

Tuo*_*asK 9

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

csvWriter.Dispose();

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

streamWriter.AutoFlush = true;

每次都会自动刷新流.


Ami*_*mit 5

这是工作示例:

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());
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

基于答案。