2

我正在开发一个程序,您可以从 csv 文件中选择一个标题(它最初会解析标题)并且我希望用户能够获取列的数据而无需读取整个文件。(制作一个列表字符串数组并提取字符串数组索引以获取信息,这是简单易行的事情)。

有没有办法我可以使用 seek 来做到这一点?也许搜索一个字符串(这将是标题)并在其列中获取信息。

这是 getHeader 功能,以防万一它有帮助......

private string[] getHeader(string path)//gets the headers from the file path specified.
    {          
        List<string> row = new List<string>();

        using (StreamReader readFile = new StreamReader(path))
        {          
            row = (readFile.ReadLine().Split(',').ToList());                
        }

        return row.ToArray();

    }

(列表和数组只是为了绕过最初为数组设置大小......)

谢谢!

4

1 回答 1

2

不可能的。

搜索可以到文件中的一个确定位置。如果您有一个具有巨大记录长度和少量记录的固定长度记录 (SDF/COBOL) 文件,这将是一个不错的主意。

不幸的是,.csv 根据定义是可变长度记录。您只能根据在记录末尾点击 cr/lf 来判断一条记录在哪里停止和开始。

即使对于大多数固定记录格式,这也不是一个好主意。由于缓冲,操作系统无论如何都会读取整个文件,因为您将寻求比操作系统预加载更小的数量。

我明白你为什么要这样做;直觉上,听起来会更快。虽然您应该始终牢记速度设计您的代码,但这已经足够低级,可以称为“过早的优化” - 谷歌。基本上,您必须通过编写它来向自己证明它运行缓慢,然后,当您看到它对功能造成巨大障碍时,您可以进行优化。

不要自己解析!

MS对此有一个总成。Microsoft.VisualBasic.FileIO.TextFieldParser. 是的,您可以将它与 C# 一起使用(即使下面的示例是在 VB 中,您也可以弄清楚您需要做什么)。不要为包含对 VB 的引用而感到自豪。口袋里的时间和金钱很重要,不能说“我不会用 10 英尺长的杆子碰任何 VB”。更改是程序集已经在您的目标 PC 上。唯一需要注意的是您是否有程序安装包下载大小问题,或者正在部署到非 PC 平台。

    Using Reader As New Microsoft.VisualBasic.FileIO.TextFieldParser(CSVPath)

        Reader.TextFieldType = Microsoft.VisualBasic.FileIO.FieldType.Delimited
        Reader.Delimiters = New String() {","}
        Reader.TrimWhiteSpace = True
        Reader.HasFieldsEnclosedInQuotes = True

        While Not Reader.EndOfData
            Try
                Dim st2 As New List(Of String)
                st2.addrange(Reader.ReadFields())
                If iCount > 0 Then ' ignore first row = field names
                    Dim p As New clsPerson
                    p.CSVLine = st2
                    While p.CSVLine.Count < 15
                        p.CSVLine.Add("")
                    End While
                    p.FirstName = st2(1).Trim
                    If st2.Count > 2 Then
                        p.MiddleName = st2(2).Trim
                    Else
                        p.MiddleName = ""
                    End If
                    p.LastNameSuffix = st2(0).Trim
                    If st2.Count >= 6 Then
                        p.TestCase = st2(5).Trim
                    End If
                    If st2(3) > "" Then
                        p.CertsFromCase.Add(st2(3))
                    End If
                    cases.Add(p)
                Else
                    stFirstRow = CatLine(st2.ToArray)
                    Dim st3(6) As String
                    For kk As Integer = 0 To Math.Min(st2.Count - 1, 5)
                        st3(kk) = st2(kk)
                    Next
                    If 0 = InStr(st3(0), "Last Name", CompareMethod.Text) Or _
                     0 = InStr(st3(1), "First Name", CompareMethod.Text) Or _
                     0 = InStr(st3(2), "Middle Name", CompareMethod.Text) Or _
                     0 = InStr(st3(3), "Policy", CompareMethod.Text) Or _
                     0 = InStr(st3(5), "Test Case", CompareMethod.Text) Then
                        stFirstRow = "Last Name,First Name,Middle Name,Policy,,Test Case #" & vbCrLf & stFirstRow
                    End If
                End If
            Catch ex As Microsoft.VisualBasic.FileIO.MalformedLineException
                MsgBox("Line " & ex.Message & " is not valid and will be skipped.")
            End Try
            iCount += 1
        End While
    End Using
于 2012-05-17T15:43:06.397 回答