不可能的。
搜索可以到文件中的一个确定位置。如果您有一个具有巨大记录长度和少量记录的固定长度记录 (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