2012-06-24 117 views
1

我有一个大型日志文件,需要使用Windows 8上的F#进行分析。服务器不断运行,通过添加新行来写入日志文件的末尾。日志文件每分钟检查一次更改。我不想重新整理整个文件,而宁愿只从最后读取,并将新添加的行与前一个解析的结果合并。更好的是,我希望只要文件被更改就能够注册一个回调。那可能吗?处理大文件

+0

当然,理想情况下,最好是只要重新配置写入到最后的服务器的日志文件也写入一些你公开的服务(如果服务器使用的是log4net,或者甚至跟踪api,不应该太难)... –

+0

是的,那很好。不幸的是,服务器只是一个.exe,我没有它的来源。 –

+4

您可以使用[FileSystemWatcher](http://msdn.microsoft.com/en-us/library/system.io.filesystemwatcher.aspx)来触发您的处理程序。处理程序反过来会记住上次访问的偏移量(或前一个文件大小),然后“搜索()”并读取新行。请注意正确打开文件,以免发生访问冲突。它还取决于服务器如何打开文件进行写入。 – bytebuster

回答

1

您可以通过文件流执行此操作Seek()。事情是这样的:

open System.IO 

let WatchLog directory file = 
    // Keep track of last read position 
    let lastRead = ref 0L 

    // Function that's called whenever the file changes 
    let processLog (e : FileSystemEventArgs) = 
     // Open file, and seek to the last read location 
     use fs = new FileStream(Path.Combine(directory, file), FileMode.Open, FileAccess.Read) 
     fs.Seek(!lastRead, SeekOrigin.Begin) |> ignore 

     // Read the rest of the file 
     use sr = new StreamReader(fs) 
     printfn "Reading log: %A" (sr.ReadToEnd()) 

     // Store the length so that we know how much to seek over next time 
     lastRead := fs.Length 
     () 

    // Create a FS watched to be notified when a file changes 
    let fs = new FileSystemWatcher(directory, file) 
    fs.Changed.Add(processLog) 
    fs.EnableRaisingEvents <- true 

WatchLog "M:\Coding\" "TestLog.txt" 

然而,出于某种原因,我的机器上我得到“该进程无法访问该文件,因为它正由另一个进程内”的错误,这是我无法追查。 use语句应该在它们超出范围时进行处置,甚至对Close的明确调用也不会修复它:/

+2

如果你是从不同的线程或进程做到这一点,那么我会期望这个消息。在最后添加一个参数 - “,FileMode.Open,FileAccess.Read,FileShare.ReadWrite) - 可能会修复它,但作者也必须共享(我还没有测试过任何东西)。 –