我有一个表示日志的基于文本的数据库,按时间戳排序。出于测试目的,我的数据库大约有 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 行的内容,等等。行内容可能很长。
一个重要的注意事项是每个文件的行号都是按顺序排列的。也就是说,下次我cpu.txt
在数据库中遇到一个条目时,它将以 line4
作为行号。但是,我可能仅在来自 ram.txt、harddrive.txt、graphics.txt 等的数千个其他条目之后才看到 cpu.txt 条目。
我考虑过使用以下代码行中的内容:
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());
}
但是,File.ReadLines()
不想在每次迭代后处理它的 TextReader 吗?效率不高?
我也有这个想法,为我需要在字典中读取的每个文件保留一个 StreamReader:
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 类的链接,但我只知道我需要在的行号,而不是偏移量)但不认为他们具体回答我的问题。