我有几个日志文件需要根据时间戳进行解析和组合。他们的格式是:
GaRbAgE fIrSt LiNe
[1124 0905 134242422 ] Logs initialized
[1124 0905 134242568 SYSTEM] Good log entry:
{ Collection:
["Attribute"|String]
...
[1124 0905 135212932 SYSTEM] Good log entry:
如你所见,我不需要第一行 我目前正在使用一些正则表达式来解析每个文件:一个表达式确定我是否已经初始化" Logs"我不关心和抛弃的线;另一个确定我是否有一个" Good log entry&#34 ;,我保留并解析;一些好的日志条目跨越多行。我只是接受多行的日志。但是,代码当前还捕获第一个垃圾行,因为它与Regex视点中的多行日志注释无法区分。此外,从我所读的Regex不是这里的解决方案(Parsing a log file with regular expressions)。
有许多日志文件,它们可能会变得相当大。出于这个原因,我在缓冲之前每次只读取50行,然后将它们组合成一个单独的文件。只要存在非空文件,我就遍历每个文件。下面是一个代码示例,我用一些解释替换了一些条件和变量。
while (there are non-null files left to read)
{
foreach (object logFile in logFiles) //logFiles is an array that stores the log names
{
int numLinesRead = 0;
using (StreamReader fileReader = File.OpenText(logFile.ToString()))
{
string fileLine;
// read in a line from the file
while ((fileLine = fileReader.ReadLine()) != null && numLinesRead < 50)
{
// compare line to regex expressions
Match rMatch = rExp.Match(fileLine);
if (rMatch.Success) // found good log entry
{
...
你如何跳过第一条垃圾线?不幸的是,它并不像简单地消费ReadLine()
一行那么容易,因为StreamReader在一个循环中,我最终会每50个其他行删除一行。
我想保留一个列表或文件数组,我已经跳过了第一行(为了不多跳过它),但这有点难看。我还想到摆脱using
语句并在循环之前打开StreamReader,但我不想那样做。
编辑我刚刚意识到我的实施可能根本不正确。当StreamReader关闭并处置时,我相信我之前在文件中的位置将会丢失。在这种情况下,我是否仍然应该使用没有using
结构的StreamReader,或者我应该考虑使用不同类型的文件阅读器?
答案 0 :(得分:2)
你可以使用这样的东西:
而不是:
using (StreamReader fileReader = File.OpenText(logFile.ToString()))
{
string fileLine;
// read in a line from the file
while ((fileLine = fileReader.ReadLine()) != null && numLinesRead < 50)
{
这样做:
int numLinesRead = 0;
foreach (var fileLine in File.ReadLines(logFile.ToString()).Skip(1))
{
if (++numLinesRead >= 50)
break;
答案 1 :(得分:1)
将另一个参数添加到文件中位置的方法中。它第一次为零,你可以在进入循环之前使用该行。之后,您可以使用它来定位最后一个停止的流。
例如
long position = 0;
while position >= 0
{
position = ReadFiftyLines(argLogFile,0);
}
public long ReadFiftyLines(string argLogFile, long argPosition)
{
using(FileStream fs = new FileStream(argLogFile,FileMode.Open,FileAccess.Read))
{
string line = null;
if (argPosition == 0)
{
line = reader.Readline();
if (line == null)
{
return -1; // empty file
}
}
else
{
fs.Seek(argPosition,SeekOrigin.Begin);
}
StreamReader reader = new StreamReader(fs);
int count = 0;
while ((line = reader.ReadLine() != null) && (count < 50))
{
count++;
// do stuff with line
}
if (line == null)
{
return -1; // end of file
}
return fs.Position;
}
}
或某些。