我正在开发一个程序,您可以从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();
}
(列表和数组只是为了解决最初设置数组的大小...)
谢谢!
答案 0 :(得分:2)
Seek可以在文件中找到一个明确的位置。如果您有一个具有巨大记录长度和少量记录的固定长度记录(SDF / COBOL)文件,这将是一个好主意。
不幸的是,.csv的定义是可变长度记录。您只能根据记录末尾的cr / lf来判断一条记录的停止和开始位置。
即使使用大多数固定记录格式,这也不是一个好主意。由于缓冲,操作系统无论如何都会读取整个文件,因为您将提前获取较小的数量,然后操作系统已预先加载。
我明白你为什么要这样做;直观地说,它听起来会更快。虽然你应该始终考虑速度设计你的代码,但这个级别很低,足以被称为“过早优化” - 谷歌。基本上你必须通过编写它来证明它运行缓慢,然后,当你发现它是功能的一个巨大障碍时,你可以进行优化。
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