我工作的地方有一个日志文件,其中包含以下行:
31201007061308000000161639030001
这是这样读的:
31 |年(4)|月(4)|天(2)|小时(2)|分钟(2)| 000000 |设施(3)|徽章(5)| 0001
所以每条记录应该有一条线,但是会发生这样的事情:
31201007192000000000161206930004 31201007192001000000161353900004 31201031201007192004000000161204690004 31201007192004000000090140470004 31201007192005000000090148140004 3120100719200500031201007191515000000161597180001 31201007191700000000161203490001 31201007191700000000161203490001 31201007191700000000161202830001 31201007191700000000
这是因为应该读取该文件的软件,有时它会遗漏一些新的记录,而负责人会将旧记录复制到文件的末尾。所以基本上就是因为人为错误。
当记录未保存在DB中时,我必须搜索该文件。起初我只做了一个遍历文件中每个记录的cicle,但它真的很慢,上面提到的问题使它变慢了。我现在采用的方法是使用正则表达式,就像这样:
//Starts Reader
StreamReader reader = new StreamReader(path);
string fileLine = reader.ReadLine();
while (!reader.EndOfStream)
{
//Regex Matcher
Regex rx = new Regex(@"31\d\d\d\d\d\d\d\d\d\d\d\d000000161\d\d\d\d\d0001");
//Looks for all valid lines
MatchCollection matches = rx.Matches(fileLine);
//Compares each match against what we are looking for
foreach (Match m in matches)
{
string s = m.Value;
compareLine(date, badge, s);
}
reader.ReadLine();
}
reader.Close(); //Closes reader
我的问题是:搜索文件的好方法是什么?我应该先订购/清洁吗?
答案 0 :(得分:2)
您可能最好遵循以下步骤:
DateTime
对象以及任何其他相关字段。如果你稍微清理它,可以使用Regex轻松完成。使用捕获组和转发器。对于一年,您可以使用(\d{4})
获取行中的4个数字,而不是\d\d\d\d
。List<MyStruct>
,将每行保存为对象。使用LINQ搜索列表,例如:
var searchResults = from eachEntry in MyList where eachEntry.Date > DateTime.Now and eachEntry.facility.Contains("003") select eachEntry;
此外,将此行添加到您的正则表达式,它会加快速度,如果只是几毫秒:
MatchCollection matches = rx.Matches(fileLine, RegexOptions.Compiled);
答案 1 :(得分:0)
如果您(提前)知道您正在寻找哪个条目,即I.e。你完全知道你正在寻找的日期,设施和批次,你根本不需要解析数据。生成期望的字符串并进行简单的字符串搜索而不是使用正则表达式可能会更快:
string expectedValue = getExpectedValue(date, badge);
// expectedValue = "31201007192000000000161206930004"
foreach (string line in lines)
{
if (line.IndexOf(expectedValue) >= 0)
{
// record found
}
}
如果您只对该文件包含您的ID感兴趣,可以将整个文件读入单个字符串并按
进行搜索string completeFile = GetFileContents(file);
if (completeFile.IndexOf(expectedValue) >= 0)
{
// record found
}