【问题标题】:Using CsvReader From LumenWorks with ";" delimiter将 LumenWorks 中的 CsvReader 与“;”一起使用分隔符
【发布时间】:2013-07-27 12:40:36
【问题描述】:

我对 LumenWorks 的 CsvReader 有两个小问题。

我的第一个*.csv 文件有一个; 分隔符。没什么大不了的,我只需要更改阅读器中的分隔符属性,但实际上比这更棘手,因为标题也以 ; 结尾,但不是行。

例如:

Column1;Column2;Column3;
1;Michael;Page
2;Michael;Jackson
...

有没有办法向读者表明它?

第二个问题如何动态选择要导入的列?

我的代码是这样写的:

Public Sub ImportCSV2Data(ByVal filename As String, ByRef gridToShow As GridControl, ByVal column2Import() As Integer)
    Dim csvCopy As CachedCsvReader = New CachedCsvReader(New StreamReader(filename), True, ";"c)
    Dim processedCopy = csvCopy.Select(Function(showColumn) New With{.SAPNo = column(0),.CCode = column(2)})

    gridToShow.DataSource = processedCopy
End Sub

但我怎样才能使选定的列取决于 column2Import 中的值?

谢谢

【问题讨论】:

    标签: .net vb.net linq csv


    【解决方案1】:

    依赖CSVReader 并不是一件坏事,但如果您有特殊要求,也许依赖传统的StreamReader 会更容易,而不是花时间进行所需的修改。示例代码:

     Dim sr As System.IO.StreamReader = New System.IO.StreamReader("target CSV file path")
     Dim line As String
    
     'Adapt this code to retrieve the column names from the file itself or from other source
     Dim getColumnNames As Boolean = True
     Dim columnNames() As String = Nothing
    
     Do
         line = sr.ReadLine()
         If (line IsNot Nothing) Then
             if(line.Contains(";")) then
                 If (columnNames Is Nothing And getColumnNames) Then
                     columnNames = line.Split(";")
                 Else
                     Dim curRowVals() As String = line.Split(";")
                     'All the row values
                 End If
             End If
         End If
     Loop Until line Is Nothing
    

    【讨论】:

    • 如果我们将And 替换为AndAlso,我们就不会再出现错误了。而且您的代码确实是一个好主意,但事实是我的 csv 中有 20k 行,这就是我尝试使用 csvreader 进行快速阅读过程的原因。 Mayby 我可以尝试打开 csv 文件,从标题行中删除最后一个 ;,保存并通过 csvreader 读取它吗?
    • @Rave 我不太确定 CSVreader 是否比传统的流式阅读器快得多。仅仅打开和编辑文件就意味着浪费了太多时间。 CSVreader 也不像上面提出的代码那样灵活。为什么不用你的 20k 文件测试这段代码,看看需要多长时间? PS:感谢AndAlso的评论;最近,我通常使用 C# 编程,有时会忘记这些 VB 细节。
    • @Rave 您的 AndAlso 评论很好(主要针对更习惯 C# 的人),但我介绍的更正也很好,因此不需要更改。甚至循环也可能在顶部有一段时间,因此可以忽略 isnot nothing 条件(或 AndAlso)。有很多选项都可以;这里重要的是此代码对您的特定情况的适用性(顺便说一句,此特定的流式阅读器代码直接来自 MSDN)。
    • @Rave 我现在明白你的问题了!!!您没有正确理解正在处理的维度。尝试一种简单的方法使其工作(我希望您将进一步分析并提出适合您情况的最佳配置)。我将通过评论将其放入,因为它不会真正影响我的答案(= 依赖传统的流式阅读器并处理其中的所有信息)。这样做...
    • @Rave Dim datatable As DataTable = New DataTable() datatable.Columns.Add(0) datatable.Columns.Add(1) datatable.Columns.Add(2) 获取每一行的值后(实际上是值的数组),这样写: Dim curRowVals() As String = line.Split(";") datatable.Rows.Add(curRowVals(0), curRowVals(1), curRowVals(2)) 在这个将相应的行/列写入数据表的方式。在循环之外,通过执行以下操作将数据表分配给数据网格视图:DataGridView1.DataSource = datatable
    【解决方案2】:

    回答“第二个问题”如何选择列的子集:

    Dim result As IEnumerable(Of String()) = csvCopy.
        Select(Function(fields) fields.Where(Function(f, i) column2Import.Contains(i))
                                      .ToArray()) 
    

    【讨论】:

    • 它不起作用而不是我的 csv 数据我有长度、长长度、等级、同步根、只读的列...当我调用 CsvReader 时,它看起来像同样的问题而不是 CachedCsvReader。
    • Column2Import 包含必须选择的列的索引(对不起,如果我不够清楚)。
    • @Rave:linq 查询只选择column2Import 中的列索引。每行的fields 对象包含String[] 的所有列,提供索引的overload of Where 用于仅选择所需的列。 ToArray 从这些创建一个新数组。
    【解决方案3】:

    睡了一夜之后,我想到了这个主意:

    Dim csvCopy As CachedCsvReader = New CachedCsvReader(New StreamReader(filename), True, ";"c)
    csvCopy.MissingFieldAction = MissingFieldAction.ReplaceByEmpty
    
    Dim headers() As String = csvCopy.GetFieldHeaders
    For Each column As Integer In column2Import
        datatable.Columns.Add(headers(column))
    Next
    While csvCopy.ReadNextRecord()
        Dim csvRow As DataRow = datatable.NewRow
        Dim i As Integer = 0
        For Each column As Integer In column2Import
            csvRow(i) = csvCopy(column)
            i += 1
        Next
        datatable.Rows.Add(csvRow)
    End While
    

    csvCopy.MissingFieldAction = MissingFieldAction.ReplaceByEmpty 解决了我的第二个问题,其余的解决了我的第一个问题

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-01-20
      • 2012-03-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-12-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多