如何编写对文件更改作出反应的Scala脚本

如何编写对文件更改作出反应的Scala脚本,scala,Scala,我想将下面的批处理脚本更改为Scala(只是为了好玩),但是,脚本必须保持运行并侦听对*.mkd文件的更改。如果更改了任何文件,则脚本应重新生成受影响的文档。文件IO一直是我的致命弱点 #!/bin/sh for file in *.mkd do pandoc --number-sections $file -o "${file%%.*}.pdf" done 任何关于这方面的好方法的想法都将不胜感激。以下代码摘自我的回答:可以查看目录并执行特定命令: #!/usr/bin/env scal

我想将下面的批处理脚本更改为Scala(只是为了好玩),但是,脚本必须保持运行并侦听对*.mkd文件的更改。如果更改了任何文件,则脚本应重新生成受影响的文档。文件IO一直是我的致命弱点

#!/bin/sh
for file in *.mkd
do
  pandoc --number-sections $file -o "${file%%.*}.pdf"
done

任何关于这方面的好方法的想法都将不胜感激。

以下代码摘自我的回答:可以查看目录并执行特定命令:

#!/usr/bin/env scala

import java.nio.file._
import scala.collection.JavaConversions._
import scala.sys.process._

val file = Paths.get(args(0))
val cmd = args(1)
val watcher = FileSystems.getDefault.newWatchService

file.register(
  watcher, 
  StandardWatchEventKinds.ENTRY_CREATE,
  StandardWatchEventKinds.ENTRY_MODIFY,
  StandardWatchEventKinds.ENTRY_DELETE
)

def exec = cmd run true

@scala.annotation.tailrec
def watch(proc: Process): Unit = {
  val key = watcher.take
  val events = key.pollEvents

  val newProc = 
    if (!events.isEmpty) {
      proc.destroy()
      exec
    } else proc

  if (key.reset) watch(newProc)
  else println("aborted")
}

watch(exec)
用法:

watchr.scala markdownFolder/ "echo \"Something changed!\""
必须对脚本进行扩展才能将文件名注入命令。到目前为止,这段代码应该被视为实际答案的构建块

修改脚本以合并*.mkd通配符并非易事,因为您必须手动搜索文件并在所有文件上注册一个监视。重新使用上面的脚本并将所有文件放在一个目录中,这样做的另一个优点是在创建新文件时可以拾取它们


正如您所看到的,仅仅依靠Scala和javaapi,它就会变得非常庞大和混乱,使用INotify时,您最好依赖其他库或只使用bash

使用Java语言,谢谢Boris。看来这是最好的办法了。谢谢鲍勃,它几乎奏效了。但是,参数在某个地方丢失了。如果您执行了
whatchr.scala文件夹/“echo$file”
,那么它只会回显空行,而不仅仅是文件更改。感谢您迄今为止的帮助;-)哦,你是对的,我真是太蠢了,我会修改答案,解释需要做的额外更改。目前的代码只应作为Scala中WatchService的一个示例使用。还有一些项目将WatchService API封装在更人性化的抽象中。