如何等待文件创建

che*_*ino 1 java io file

我的情况如下:我有一个Java程序,从此启动了一个perl脚本。Perl脚本正在生成一个文件,Java应该在该文件上继续工作。到现在为止,我已经设定了

Thread.sleep(3000);
Run Code Online (Sandbox Code Playgroud)

让Java等待文件完成。我一直在寻找一种更优雅的方法来让Java检查文件是否存在并继续。我最后的尝试是

Boolean waitforfile = true;  
while(waitforfile){
       File f = new File(pathtofile);
       if(f.exists() && !f.isDirectory()) { waitforfile=false; }
       } 
Run Code Online (Sandbox Code Playgroud)

但这会让我陷入永无止境的循环中。还有其他方法吗?

更新:在建议上,尝试过,处理,WaitFor(); 在

    public static String syscall(String call){
    String out = "";
    try {
    String line;
    Process p = Runtime.getRuntime().exec(call);
    BufferedReader input = new BufferedReader(new InputStreamReader(p.getInputStream()));
    while ((line = input.readLine()) != null) {
      out=out+"\n"+line;
    }
    input.close();
    p.waitFor();
    } catch (Exception e) {
        System.out.println(e);
    }

    return out;
}
Run Code Online (Sandbox Code Playgroud)

这个没有等待我的perl进程被关闭。

Pet*_*rey 5

更好的方法是将文件写入一个类似的临时文件名,myscript.pl.tmp并在完成后重命名。由于重命名是原子的,因此您不会看到它处于不完整的状态。

顺便说一句,您可以使用WatchService在文件出现时得到通知。监视目录以进行更改


Mic*_*kis 5

正如@peter-lawrey 所提到的,正确的方法是java.nio.file.WatchService.

以下是等待创建文件的特定(但常见)情况的简单实现。此静态方法返回目标文件的基本文件属性(creationTime其中),或者null文件是否未显示。

public static BasicFileAttributes awaitFile(Path target, long timeout) 
    throws IOException, InterruptedException
{
    final Path name = target.getFileName();
    final Path targetDir = target.getParent();

    // If path already exists, return early
    try {
        return Files.readAttributes(target, BasicFileAttributes.class);
    } catch (NoSuchFileException ex) {}

    final WatchService watchService = FileSystems.getDefault().newWatchService();
    try {
        final WatchKey watchKey = targetDir.register(watchService, StandardWatchEventKinds.ENTRY_CREATE);
        // The file could have been created in the window between Files.readAttributes and Path.register
        try {
            return Files.readAttributes(target, BasicFileAttributes.class);
        } catch (NoSuchFileException ex) {}
        // The file is absent: watch events in parent directory 
        WatchKey watchKey1 = null;
        boolean valid = true;
        do {
            long t0 = System.currentTimeMillis();
            watchKey1 = watchService.poll(timeout, TimeUnit.MILLISECONDS);
            if (watchKey1 == null) {
                return null; // timed out
            }
            // Examine events associated with key
            for (WatchEvent<?> event: watchKey1.pollEvents()) {
                Path path1 = (Path) event.context();
                if (path1.getFileName().equals(name)) {
                    return Files.readAttributes(target, BasicFileAttributes.class);
                }
            }
            // Did not receive an interesting event; re-register key to queue
            long elapsed = System.currentTimeMillis() - t0;
            timeout = elapsed < timeout? (timeout - elapsed) : 0L;
            valid = watchKey1.reset();
        } while (valid);
    } finally {
        watchService.close();
    }

    return null;
}
Run Code Online (Sandbox Code Playgroud)