【问题标题】:How to read a huge txt file to a ObservableCollection如何将巨大的文本文件读取到 ObservableCollection
【发布时间】:2019-09-16 16:53:30
【问题描述】:

我有一个超过 200,000 行的 excel 文件。如果我使用 OleDbConnection 将其读入数据表或 ObservableCollection,然后在数据网格中显示,则需要一分钟以上。我将 xlsx 更改为制表符分隔的 txt。我发现将整个 txt 文件放入数据表中非常快。它需要不到 10 秒。如果我将整个 txt 直接放入 ObservableCollection,我想知道该怎么做。它不能逐行完成,因为它会再次花费一分钟以上。

'Define Product property    
     Public Class Product
                    Public Property Model As String
                    Public Property Opt As String
                    Public Property Description As String
                    Public Property Price As String               
     End Class

'define Products as ObservableCollection       
 Dim Products As New ObservableCollection(Of Product)()

'Read txt file to datatable
Private Sub LoadBound(ByVal fName As String)
Dim textLine As String = String.Empty
Dim splitLine As String()

CSVdata.Columns.AddRange({New DataColumn("Model"),
                          New DataColumn("Opt"),
                          New DataColumn("Description"),
                          New DataColumn("Price")})
                    CSVdata.Rows.Clear()

                    If System.IO.File.Exists(fName) Then
                        Dim objReader As System.IO.StreamReader = New System.IO.StreamReader(fName)
                        Dim contents = objReader.ReadToEnd()
                        Dim strReader = New System.IO.StringReader(contents)


        Do
            textLine = strReader.ReadLine()
            If textLine.Contains("""") Then
                textLine = textLine.Replace("""", "")

            End If
                            If textLine <> String.Empty Then
                                splitLine = textLine.Split(vbTab)

                                If splitLine(0) <> String.Empty OrElse splitLine(1) <> String.Empty Then
                                    CSVdata.Rows.Add(splitLine)

                                End If
                            End If
                        Loop While strReader.Peek() <> -1
                    End If

 End Sub

【问题讨论】:

  • 你已经有一个可观察的数据表集合。只需绑定到 DataTable 或将 DataSource 设为 DataTable。
  • 这个循环没有开始。 Loop While strReader.Peek() &lt;&gt; -1
  • 对不起。我想让它变得简单,忘记粘贴循环的开头。我加了。

标签: c# vb.net datatable datagrid observablecollection


【解决方案1】:

注释和解释。

Public Class Product
    Public Property Model As String
    Public Property Opt As String
    Public Property Description As String
    Public Property Price As String
    'Add a parameterized constructor to your class to make coding easier
    Public Sub New(Mdl As String, O As String, Desc As String, P As String)
        Model = Mdl
        Opt = O
        Description = Desc
        Price = P
    End Sub
End Class

Dim Products As ObservableCollection(Of Product)

Private Sub LoadBound(ByVal fName As String)
    'Build a List(Of Product) from the text file
    Dim lstProducts As New List(Of Product)
    Dim lines = File.ReadAllLines(fName)
    For Each line In lines
        Dim Props = line.Split(CChar(vbTab))
        Dim p As New Product(Props(0), Props(1), Props(2), Props(3))
        lstProducts.Add(p)
    Next
    'The constructor of an ObservableCollection can take a List(Of T)
    Products = New ObservableCollection(Of Product)(lstProducts)
End Sub

编辑

Public Class Product
    Public Property Model As String
    Public Property Opt As String
    Public Property Description As String
    Private strPrice As String
    Public Property Price As Double
    'Add a parameterized constructor to your class to make coding easier
    Public Sub New(Mdl As String, O As String, Desc As String, P As String)
        Model = Mdl
        Opt = O
        Description = Desc
        Dim ParsedDouble As Double
        Double.TryParse(P, ParsedDouble)
        Price = ParsedDouble
    End Sub
End Class

更改价格类型

  1. 更改属性的类型

  2. 调整 Sub New 以从字符串中获取双精度值。如果解析失败,价格将为 0。

    如果你真的想要一个 null(vb 中什么都没有),请参阅 https://docs.microsoft.com/en-us/dotnet/visual-basic/programming-guide/language-features/data-types/nullable-value-types

【讨论】:

  • 太棒了!这比数据表快 5 倍。我还有一个问题。我想将价格定义为双精度而不是字符串。如果excel中的价格列有一些单元格是空的,那么它们在txt中也是空白的。它显示 System.InvalidCastException: '从字符串 "" 到类型 'Double' 的转换无效。如何处理?谢谢。
  • 嗨,玛丽,你太棒了!按照您的建议,我可以得到 null 和 0 。它们都存在于数据中。另一个问题是 txt 中的描述中有双引号,而 excel 中的描述有逗号。我设法在我的原始代码中的 Dim strReader = New System.IO.StringReader(contents) 之后删除双引号(我编辑了我的帖子,你可以看看。)但未能在行、行或 Pros(2) 中做到这一点在新代码中。你知道为什么吗?
  • 您的 .Contains 正在寻找连续 4 个双引号的子字符串。这真的存在于源字符串中吗?字符串值看起来像 """"Hello""""?
  • 嗨,玛丽,它是"""",请参阅social.msdn.microsoft.com/Forums/en-US/… 我定义了一个新的字符串 = 行并且可以删除双引号。不明白为什么我不能直接删除。
  • 嗨,玛丽,希望我能找到你。我想和你核实一下,是否有与你教我阅读 txt 文件一样的快速阅读 .mdb 文件的方法。现在文件更改为 mdb。格式是一样的。我只能使用 OleDbConnection 来访问它。我希望更快地加载数据。
猜你喜欢
  • 1970-01-01
  • 2011-11-21
  • 2010-12-26
  • 1970-01-01
  • 2015-06-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多