Quickest way to Read Specific Line from Multiple Files one Line at a time
我有一个基于文本的数据库,该数据库代表按时间戳排序的日志。为了进行测试,我的数据库大约有10,000行,但是这个数目可能更大。其格式为:
primary_key, source_file, line_num
1, cpu.txt, 2
2, ram.txt, 3
3, cpu.txt, 3
我查询数据库,并在读取结果时想将实际数据添加到可以显示的字符串中。上面示例中的实际数据是cpu.txt中第2行的内容,其次是ram.txt中第3行的内容,依此类推。该行内容可能很长。
重要说明是每个文件的行号都是有序的。也就是说,下次我在数据库中遇到
我已经考虑过按照以下代码使用某些东西:
1 2 3 4 5 6 7 8 9 | StringBuilder odbcResults = new StringBuilder(); OdbcDataReader dbReader = com.ExecuteReader(); // query database while (dbReader.Read()) { string fileName = dbReader[1].ToString(); // source file int fileLineNum = int.Parse(dbReader[2].ToString()); // line number in source file odbcResults.Append(File.ReadLines(fileName).Skip(fileLineNum).First()); } |
但是,
我也有这个想法,为需要在Dict中读取的每个文件保留一个StreamReader:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | Dictionary<string, StreamReader> fileReaders = new Dictionary<string, StreamReader>(); StringBuilder odbcResults = new StringBuilder(); OdbcDataReader dbReader = com.ExecuteReader(); while (dbReader.Read()) { string fileName = dbReader[1].ToString(); // source file int fileLineNum = int.Parse(dbReader[2].ToString()); // line number in source file if (!fileReaders.ContainsKey(fileName)) { fileReaders.Add(fileName, new StreamReader(fileName)); } StreamReader fileReader = fileReaders[fileName]; // don't have to worry about positioning? Lines consumed consecutively odbcResults.Append(fileReader.ReadLine()); } // can't forget to properly Close() and Dispose() of all fileReaders |
您是否同意上述任何示例,或者有更好的方法吗?
对于第二个示例,我假设StreamReader会记住它的最后位置-我认为这将保存在BaseStream中。
我已经阅读了如何读取文本文件中的指定行?,在特定行读取文本文件,StreamReader并查找(第一个答案提供了到具有定位功能的自定义StreamReader类的链接,但我只知道行号我需要发言,而不是抵消),但不要以为他们会具体回答我的问题。
如果可以保证行引用在文件中严格按顺序排列(即,在要求第n行之后总是要求第n + 1行),那么选择保留
如果您可能要求第n行,然后是第n + x行(其中x是某个正数> = 1),那么我会将
您不必担心定位。这是为您处理的,因为您要按顺序阅读。
听起来您好像希望将用户选择的所有内容都存储在内存中(以便在文本框中显示),因此这对于任何可行的操作都是一个自然界限。我建议采用以下方法:
- 从数据库中读取所有匹配的元数据(即在用户指定的时间范围内)到列表中。保留一组我们需要阅读的文件。
- 创建一个与列表大小相同的新数组-这将保存最终数据
-
一次浏览一个所需文件:
- 打开文件,记住我们在第0行
- 遍历元数据列表。对于与我们当前打开的文件匹配的每个条目,向前读到右行,并填充与我们正在查看的列表条目相对应的最终数据数组元素。我们应该只需要向前阅读,因为我们仍然按照时间戳顺序进行。
- 关闭档案
此时,"最终数据数组"应完全填充。您一次只需要打开一个文件,就不需要读取整个文件。我认为这比拥有打开文件的字典更简单-除了其他功能之外,这意味着您可以为每个文件使用
这确实意味着一次将所有数据库元数据条目都存储在内存中,但是大概每个元数据条目都比最后要在内存中具有的结果数据要小,以便向用户显示结果。
即使您要遍历数据库元数据条目多次,也都将在内存中进行。与文件系统或数据库的IO相比,它应该无关紧要。
一种替代方法是在读取元数据条目时按文件名对其进行分组,并将索引保??留为元数据条目的一部分。