等到LibreOffice创建文件

时间:2014-08-03 00:14:38

标签: java shell command-line libreoffice

我正在努力解决与Java相关的LibreOffices无头模式。

My Spring网络应用程序生成ODT,将其导出为PDF文件,然后通过HTTP将其发送回用户。

会发生什么

  1. 生成ODT
  2. 执行LibreOffice无头模式(conver-to pdf)
  3. 将其发送给用户
  4. 两个和三个几乎同时发生,导致FileNotFoundException。该过程在我的旧PC上运行大约10秒,同时我的控制器已经尝试(并且失败)读取输出。

    如何在命令完成之前阻止Java继续运行。如果生成文件,这可以通过每半秒一次循环检查来完成,还是更好的方法呢?


    这是我的LibreOffice代码:

    Runtime runtime = Runtime.getRuntime();
    Process process = runtime.exec(path + program + convert + outdir + file);
    

    我的全部命令:

    "C:/progra~2/libreo~1/program/soffice.exe" --headless --invisible --convert-to pdf --outdir "C:\Users\MAX-MI~1\AppData\Local\Temp" "C:\Users\MAX-MI~1\AppData\Local\Temp\document-3328884507253560042.odt"
    

2 个答案:

答案 0 :(得分:2)

如果外部流程事实上表明它已经通过终止完成,那么您可以使用Process.waitFor()

如果外部进程可能会挂起(并且您不希望Java应用程序卡住),请使用带有参数的Process.waitFor(...)变体来指定超时。

如果外部进程 将不返回(例如,因为它是一个长时间运行的服务,不会分离...),或者它可能会在之前返回 >已创建所需的输出,然后变得更加困难:

  • 输入文件的简单方法是 poll ;例如致电File.exists()。这是低效的,特别是如果您经常和/或长时间轮询。 (但在很多情况下你可以接受它。)

  • 更复杂的方法是使用Java"文件观察器"在创建文件时获取通知的机制。在大多数平台上,这比轮询更有效。

但检查文件何时创建的问题在于,您(通常)不知道外部进程何时写入文件。如果它确实以块的形式写入文件,那么你需要实现某种启发式来检测它;例如在最后一次"文件更新"之后等待N秒事件


对于特定情况,您需要调查外部应用程序如何生成输出,并选择您的Java应用程序"检查它是否已完成"相应的策略/启发式。我希望像LibreOffice这样的人能够表现良好"。


相关问题:

答案 1 :(得分:1)

在runtime.exec(...)返回的Process对象上,可以调用waitFor()方法让线程等到进程完成。

http://docs.oracle.com/javase/7/docs/api/java/lang/Process.html#waitFor()