I need to read in a rolling log file in .NET 3.5sp1. I'm wondering what's the best way to do this? The file can get really big. An idea I had was to
我需要在.NET 3.5sp1中读取滚动日志文件。我想知道最好的方法是什么?该文件可以变得非常大。我的想法是
- Open File
- Read file to last read line (in the first case, it was 0)
- Read all remaining lines
- Close stream and remember the last line number read.
- Wait a bit.
- Rinse/repeat.
读取文件到最后读取行(在第一种情况下,它为0)
阅读所有剩余的行
关闭流并记住读取的最后一行。
等一会儿。
I'm not sure if this the best way though and efficient for the memory, considering the file can be pretty huge. And I can't have the log file being locked either :(
我不确定这是不是最好的方式,对内存有效,考虑到文件可能非常大。我不能将日志文件锁定:(
Thoughts?
3 个解决方案
#1
Get the file length and read the last piece of the file. It won't be hard to find the first line break and show everything from there on. FileStream has a Length
property, and the read
method allows you to read from one place to another.
获取文件长度并读取文件的最后一部分。找到第一个换行符并从那里显示所有内容并不难。 FileStream有一个Length属性,read方法允许您从一个地方读取到另一个地方。
Steven is right. If the other program doesn't require exclusive access, you can open read-only and be fine.
史蒂文是对的。如果其他程序不需要独占访问权限,则可以打开只读状态并保持正常。
#2
Here's an example of using a FileSystem Watcher to open the file and read the new data as it is written:
下面是使用FileSystem Watcher打开文件并在写入时读取新数据的示例:
http://www.codeproject.com/KB/cs/wintail.aspx
The example looks good, but do not for the love of Pete and all things fuzzy use lock(this). It is bad. Use a new object instead that you can share amongst all of the objects in the class.
这个例子看起来不错,但是不要因为皮特的爱而且所有的东西都模糊地使用锁(这个)。这是坏的。使用新对象,您可以在类中的所有对象之间共享。
If you open the file ReadOnly you shouldn't have a sharing violation depending on how your file has been opened by the program appending to the log file.
如果您打开ReadOnly文件,则不应该有共享冲突,具体取决于附加到日志文件的程序打开文件的方式。
#3
Can you just append to the file, rather than keeping track of where you are?
你能不能追加到文件中,而不是跟踪你的位置?
Object mLogLock = new Object(); //to make logging thread safe
string mLogFile = ""; //set your log location
string mLogDirectory = "";
public void HandleMessage(string inMessage)
{
lock (mLogLock)
{
if (!System.IO.Directory.Exists(mLogDirectory ))
{
System.IO.Directory.CreateDirectory(mLogDirectory );
}
String theMessage = DateTime.Now.ToString("s");
if (inMessage != null)
theMessage += " : " + inMessage;
StreamWriter sw = new StreamWriter(mLogFile, true);
sw.WriteLine(theMessage );
sw.Dispose();
sw.Close();
}
}
Otherwise, if you have a writer writing at one point and something else consuming, and you have no locking, then your program will corrupt your logs. That's just not even a question. You can try to lock your file by having the file opened for exclusive read/write by whatever wants to read or write to it, but then the other code will throw exceptions when it can't read it.
否则,如果你有一个作家一次写作而其他东西正在消费,并且你没有锁定,那么你的程序将破坏你的日志。这甚至都不是问题。您可以尝试通过任何想要读取或写入的文件打开文件以进行独占读/写来锁定文件,但是当其他代码无法读取时会抛出异常。
If the log file is in the same program, you can just keep all of the information in one large stream, like a MemoryStream, and use the StreamWriter as above instead (or as well as) to the MemoryStream. Then, your readers and writers can lock on the MemoryStream, rather than on the file itself. Would that help?
如果日志文件在同一个程序中,您可以将所有信息保存在一个大型流中,如MemoryStream,并使用上面的StreamWriter代替(或同样)MemoryStream。然后,您的读者和编写者可以锁定MemoryStream,而不是文件本身。那会有帮助吗?
#1
Get the file length and read the last piece of the file. It won't be hard to find the first line break and show everything from there on. FileStream has a Length
property, and the read
method allows you to read from one place to another.
获取文件长度并读取文件的最后一部分。找到第一个换行符并从那里显示所有内容并不难。 FileStream有一个Length属性,read方法允许您从一个地方读取到另一个地方。
Steven is right. If the other program doesn't require exclusive access, you can open read-only and be fine.
史蒂文是对的。如果其他程序不需要独占访问权限,则可以打开只读状态并保持正常。
#2
Here's an example of using a FileSystem Watcher to open the file and read the new data as it is written:
下面是使用FileSystem Watcher打开文件并在写入时读取新数据的示例:
http://www.codeproject.com/KB/cs/wintail.aspx
The example looks good, but do not for the love of Pete and all things fuzzy use lock(this). It is bad. Use a new object instead that you can share amongst all of the objects in the class.
这个例子看起来不错,但是不要因为皮特的爱而且所有的东西都模糊地使用锁(这个)。这是坏的。使用新对象,您可以在类中的所有对象之间共享。
If you open the file ReadOnly you shouldn't have a sharing violation depending on how your file has been opened by the program appending to the log file.
如果您打开ReadOnly文件,则不应该有共享冲突,具体取决于附加到日志文件的程序打开文件的方式。
#3
Can you just append to the file, rather than keeping track of where you are?
你能不能追加到文件中,而不是跟踪你的位置?
Object mLogLock = new Object(); //to make logging thread safe
string mLogFile = ""; //set your log location
string mLogDirectory = "";
public void HandleMessage(string inMessage)
{
lock (mLogLock)
{
if (!System.IO.Directory.Exists(mLogDirectory ))
{
System.IO.Directory.CreateDirectory(mLogDirectory );
}
String theMessage = DateTime.Now.ToString("s");
if (inMessage != null)
theMessage += " : " + inMessage;
StreamWriter sw = new StreamWriter(mLogFile, true);
sw.WriteLine(theMessage );
sw.Dispose();
sw.Close();
}
}
Otherwise, if you have a writer writing at one point and something else consuming, and you have no locking, then your program will corrupt your logs. That's just not even a question. You can try to lock your file by having the file opened for exclusive read/write by whatever wants to read or write to it, but then the other code will throw exceptions when it can't read it.
否则,如果你有一个作家一次写作而其他东西正在消费,并且你没有锁定,那么你的程序将破坏你的日志。这甚至都不是问题。您可以尝试通过任何想要读取或写入的文件打开文件以进行独占读/写来锁定文件,但是当其他代码无法读取时会抛出异常。
If the log file is in the same program, you can just keep all of the information in one large stream, like a MemoryStream, and use the StreamWriter as above instead (or as well as) to the MemoryStream. Then, your readers and writers can lock on the MemoryStream, rather than on the file itself. Would that help?
如果日志文件在同一个程序中,您可以将所有信息保存在一个大型流中,如MemoryStream,并使用上面的StreamWriter代替(或同样)MemoryStream。然后,您的读者和编写者可以锁定MemoryStream,而不是文件本身。那会有帮助吗?