csv - 将 CsvHelper 与流一起使用

标签 csv stream streamreader blazor csvhelper

我正在尝试使用 CsvHelper 读取 CSV 文件并从中创建数据表。第一行将是提供列名的标题记录,但除此之外,文件的结构是未知的。如果我使用以下代码(取自 CsvHelper 作者的示例),它就可以工作。

using (var reader = new StreamReader("path\\to\\file.csv"))
using (var csv = new CsvReader(reader))
{
    // Do any configuration to `CsvReader` before creating CsvDataReader.
    using (var dr = new CsvDataReader(csv))
    {        
        var dt = new DataTable();
        dt.Load(dr);
    }
}

但是,如果我使用 StreamReader 的备用构造函数将 Stream 作为参数而不是文件路径,则 CsvDataReader 的创建将失败并显示“不支持同步读取”的错误消息。

我已经尝试了 CsvHelper 的其他几种方法来尝试以不同方式处理数据,但是每当通过传入 Stream 而不是文件路径来创建 StreamReader 时,我都会遇到同样的错误。我开始怀疑真正的问题是在于 StreamReader 的实现还是在于 CsvHelper。在我的情况下(一个 Blazor 服务器应用程序),传入流更有意义。有任何想法吗?

编辑:

我相信 David Specht 是正确的,因为我使用的特定流有一些独特之处。在进一步的测试中,我发现一些字符串确实有效。在出现错误的情况下,我正在使用 IFileListEntry.Data 流接口(interface)从 Steve Sanderson 的 BlazorInputFile 组件(在 GitHub 上)读取流。我怀疑它的实现中有什么东西导致了我得到的错误。如果是这种情况,那么解决方法会有所帮助。 (也许从另一个流创建一个流以在异步流和同步流之间切换?还不确定该怎么做,但我打算试一试。)

最佳答案

正如 David Specht 在他的回答中指出的,以及我在对原始问题的编辑中指出的那样,它确实适用于某些流。在下面的示例中,流的实现中的某些内容 file.Data 不能很好地与 CsvHelper 一起使用,从而导致“不支持同步读取”错误。此特定流是 IFileListEntry.Data 实例,来自 BlazorInputFile 组件,由 Steve Sanderson 创建并在 GitHub 上提供。 (总而言之,这个组件似乎工作得很好,记住我使用的是 0.1.0-preview-00002 版本,所以谢谢,史蒂夫!)

通过使用 Stream.CopyToAsync() 将流复制到新流,问题就消失了。要记住的一个警告是,在执行此函数后,输入流和输出流都将位于流的末尾。将用于创建 CsvReader 的流必须设置回开头,以便 CsvDataReader 构造函数正常工作。如果不这样做,将出现“未找到 header 记录”错误。

以下示例对我有用,希望对其他人有所帮助!

using (var stream2 = new MemoryStream())
{
    await file.Data.CopyToAsync(stream2);   // although file.Data is itself a stream, using it directly causes "synchronous reads are not supported" errors below.
    stream2.Seek(0, SeekOrigin.Begin);      // at the end of the copy method, we are at the end of both the input and output stream and need to reset the one we want to work with.
    var reader = new System.IO.StreamReader(stream2);

    using (var csv = new CsvReader(reader))
    {
        using (var dr = new CsvDataReader(csv)) // error happens here when "file.Data" is used as the stream: "Synchronous reads are not supported"
                                                // error happens here when the stream isn't reset to the beginning: "No header record was found"
        {
            var dt = new DataTable();
            dt.Load(dr);
        }
    }
}

关于csv - 将 CsvHelper 与流一起使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58829430/

相关文章:

c# - 我应该将 StreamReader/Writer 与 NetworkStream 一起用于 C# 服务器/客户端吗?

python - 如何读取子进程标准输出的第一个字节,然后在 Python 中丢弃其余字节?

c# - 阅读文本段落,使用 StreamReader 获取下一行

r - 使用 R 中 readr 中的 read_csv 将文本作为指定列以 [type] 打开

android - 将csv导入mysql和sqlite时换行

php - 我是否采取了正确的方法来处理这些文件? (带有 PHP 的 CSV)

excel - 使用管道分隔符将 Excel 导出为 CSV,无需更改列表分隔符设置

java - FindBugs :"may fail to close stream ",如何解决?

java - ImageIO.read 关闭输入流

c# - 将文件的前 10 行提取为字符串