Haskell:无需轮询(类似于Linux中的inotify)监视文件

10
有没有一个Haskell库函数可以在不轮询的情况下监控文件?
使用轮询,我会做这样的事情:
monitor file mtime handler = do
    threadDelay n -- sleep `n` ns
    t <- getModificationTime file
    if t > mtime
        then handler >> monitor file t handler
        else monitor file mtime handler

我想要的是类似于阻塞式的getModificationTime,它会被系统唤醒。有可用的东西吗?
如果只在POSIX系统上可用,那么我会非常满意,但越便携越好:-)
编辑:我知道 hinotify,但我使用的是Mac(这就是我提到POSIX的原因)。

3
根据平台进行封装hinotitykqueue可能会很有意思。 - singpolyma
有趣的问题。很抱歉我也不知道,Windows 上有类似的东西吗? - AndrewC
3个回答

10

7
有一个GSoC项目,其结果是 fsnotify 包,它使用系统特定的库,并回退到轮询。在Mac上,它使用hfsevents

这个库看起来很不错。我尝试构建和安装它(GHC 7.0.3,Mac OS X 10.6),但由于hfsevents的问题,它无法正常工作。因此,我将坚持使用上述解决方案。 - scravy
如果您能向hfsevents的维护者提交错误报告,以便他可以修复它,那将是非常好的。 - Michael Snoyman

5

Sjoerd Visscher建议的程序包非常好用(在GHC 7.0.3和kqueue 0.1.2.4,Mac OS X 10.6雪豹下使用)。

我使用它编译了一个快速示例(因为我找不到API文档,但是在github上有一些示例):

import Control.Concurrent.MVar
import System.KQueue.HighLevel (watchFile, EventType, Watcher)
import System.Environment (getArgs)

watch :: MVar EventType -> FilePath -> IO Watcher
watch chan file =
    let handler ev = putMVar chan ev
    in  watchFile file handler

listen :: MVar EventType -> IO ()
listen chan = takeMVar chan >>= print >> listen chan

main :: IO ()
main = do
        args <- getArgs
        chan <- newEmptyMVar
        mapM (watch chan) args
        listen chan

这将创建一个小程序,您可以将文件路径作为参数传递并监视这些文件。事件通过一个 MVar 反馈,由主线程读取,该线程基本上是由 listen 实现的循环。该程序必须使用 ^C 终止,因为它设计为永久运行。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接