C# CsvHelper 未向内存流写入任何内容

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/13646105/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-10 09:19:42  来源:igfitidea点击:

CsvHelper not writing anything to memory stream

c#csvhelper

提问by Ian Cotterill

I have the following method:

我有以下方法:

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();
    }
}

Which is being called with a list of objects - eventually from a database, but since something is not working I'm just populating a static collection. The objects being passed are as follows:

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

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; }
    }
}

What I'm trying to do is write a collection to a csv for download in an MVC application. Every time I try to write to the method though, the MemoryStream is coming back with zero length and nothing being passed to it. I've used this before, but for some reason it's just not working - I'm somewhat confused. Can anyone point out to me what I've done wrong here?

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

Cheers

干杯

采纳答案by Eli Gassert

Put csvWriter.Flush();before you return to flush the writer/stream.

csvWriter.Flush();在您返回以刷新写入器/流之前放置。

EDIT: Per Hyman's response. It should be the stream that gets flushed, not the csvWriter. streamWriter.Flush();. Leaving original solution, but adding this correction.

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

EDIT 2: My preferred answer is: https://stackoverflow.com/a/22997765/1795053Let the using statements do the heavy lifting for you

编辑 2:我的首选答案是:https: //stackoverflow.com/a/22997765/1795053让 using 语句为您完成繁重的工作

回答by TuomasK

There is no flush in csvWriter, the flush is in the streamWriter. When called

csvWriter 中没有刷新,刷新在 streamWriter 中。被调用时

csvWriter.Dispose();

csvWriter.Dispose();

it will flush the stream. Another approach is to set

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

streamWriter.AutoFlush = true;

streamWriter.AutoFlush = true;

which will automatically flush the stream every time.

每次都会自动刷新流。

回答by Josh Close

You already have a usingblock which is great. That will flush your writer for you. You can just change your code slightly for it to work.

你已经有了一个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();
}

If you turn AutoFlushon, you need to be careful. This will flush after every write. If your stream is a network stream and over the wire, it will be very slow.

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

回答by Josh

Putting all these together (and the comments for corrections), including resetting the memory stream position, the final solution for me was;

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

        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.
            }
        }

In case the helps someone else!

万一帮助别人!

回答by Amit

Here is working example:

这是工作示例:

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());
        }
    }
}

Based on thisanswer.

基于这个答案。