我正在寻找一种从txt文件中读取数据的方法。文本文件具有这种结构(固定长度字段):
0000 AAAAAA BBBBBB CCCCCCCC
0000 JJJJJJ III RRRRRR
1111 XXXX YYYYYYYY ZZZZZZZZ
1111 WW PPPPPPPP ZZZZZZZZ
1111 XXXX YYYYYYYY ZZZZZZZZ
2222 XXXX YYYYYYYY ZZZZZZZZ
...
我必须通过第一个字段,在某些字典列表列表或类似内容中将它们分组。对于这个特定的例子,解决方案是:
id(list): 0000,1111,2222.....
(content)List: 0000
field1(list): AAAAAA,JJJJJJ
field2(list): BBBBBB,III
field3(list): CCCCCCCC,RRRRRR
(content)List: 1111
field1(list): XXXX,WW,XXXX
field2(list): YYYYYYYY,PPPPPPPP,YYYYYYYY
field3(list): ZZZZZZZZ,ZZZZZZZZ,ZZZZZZZZ
(content)List: 2222
field1(list): XXXX...
field2(list): YYYYYYYY...
field3(list): ZZZZZZZZ...
现在我将整个txt存储在一个字符串列表中(每行一个)。
我怎样才能在vbnet中执行此操作?你觉得这个问题有更好的方法吗?
谢谢,祝你新年快乐
答案 0 :(得分:0)
您可以使用LINQ创建一个以第一列为键的词典:
Dim fileName = "C:\Temp\Test.txt"
Dim allLines = IO.File.ReadAllLines(fileName)
Dim query = From line In allLines
Select Columns = Microsoft.VisualBasic.Split(line, vbTab)
Select ID = If(Columns.Count <> 0, Columns(0), " "), Values = Columns.Skip(1).ToList
Group By ID Into Group
Select ID, Group
' create a Dictionary from the LINQ-Query '
Dim dict = query.ToDictionary(Function(grp) (grp.ID))
' iterate all Dictionary-Entries '
For Each entry In dict
Dim key = entry.Key ' f.e 0000
For Each grp In entry.Value.Group
Dim id = grp.ID ' f.e 0000 (can repeat how we see in your example) '
Dim values As List(Of String) = grp.Values
' f.e. (0) "AAAAAA" (1) "BBBBBB" (2) "CCCCCCCC" '
Next
Next
如果您不熟悉LINQ(并且您使用的是.NET 4.0),我建议使用List(Of Tuple(Of String, List(Of String)))
,因为允许重复(字典是不可选的)。
Dim data = New List(Of Tuple(Of String, List(Of String)))
For Each line In allLines
Dim Columns = Microsoft.VisualBasic.Split(line, vbTab)
Dim ID = If(Columns.Count <> 0, Columns(0), "[empty-line]")
data.Add(Tuple.Create(ID, Columns.ToList))
Next
' iterate the collection and read values '
For Each item In data
Dim ID = item.Item1
Dim Columns = item.Item2
Next
http://msdn.microsoft.com/en-us/library/system.tuple.aspx
修改强>:
如果您因为不使用.NET 4.0而无法使用元组,请尝试按照“oldschool” - 方法创建Dictionary(Of String, List(Of List(Of String)))
。
它产生确切的期望结果(与其他方式不同,因为到目前为止我已经误解了你的要求):
Dim allLines = IO.File.ReadAllLines(fileName)
Dim data As New Dictionary(Of String, List(Of List(Of String)))
For Each line In allLines
Dim cols = line.Split(ControlChars.Tab)
Dim ID As String
If cols.Length <> 0 AndAlso cols(0).Length <> 0 Then
ID = cols(0)
If data.ContainsKey(ID) Then
Dim columnLists = data(ID)
For colIndex As Int32 = 1 To cols.Length - 1 'skip first(id)-column
If columnLists.Count >= colIndex Then
Dim columnList = columnLists(colIndex - 1)
columnList.Add(cols(colIndex))
Else
Dim newColumnList As New List(Of String)
newColumnList.Add(cols(colIndex))
columnLists.Add(newColumnList)
End If
Next
Else
Dim columnLists = New List(Of List(Of String))
For colIndex As Int32 = 1 To cols.Length - 1 'skip first(id)-column
Dim newColumnList As New List(Of String)
newColumnList.Add(cols(colIndex))
columnLists.Add(newColumnList)
Next
data.Add(ID, columnLists)
End If
End If
Next
如何阅读值:
Dim idList = data.Keys ' List of all ID-Keys '
For Each id As String In idList
Dim content As List(Of List(Of String)) = data(id)
Dim field1List As List(Of String) = content(0) ' AAAAAA,JJJJJJ
Dim field2List As List(Of String) = content(1) ' BBBBBB,III
' ....
Next
答案 1 :(得分:0)
您可以使用StreamReader。并做这样的事情(对不起它在c#但你明白了):
using(StreamReader r = new StreamReader("@C:\somefile.txt"))
{
while(!r.EndOfStream)
{
string line = r.ReadLine();
string[] data = line.Split(new string[] { " " }); //use a seperator that is approriate
//constructor the dictionary yourself
}
}
编辑:然后,对于您的结构,您有一个字典:
IDictionary - Key:id Value:如果你没有像@Tim建议那样访问id,则可以创建你自己的元组类。
如果你可以做某事而不是使用泛型我会建议。
public class Tuple<T,Q,R>
{
public T First { get; set; }
public Q Second { get; set; }
public R Third { get; set; }
}