等到 LibreOffice 创建文件
Posted
技术标签:
【中文标题】等到 LibreOffice 创建文件【英文标题】:Wait until LibreOffice created file 【发布时间】:2014-08-03 00:14:37 【问题描述】:我正在努力解决与 Java 相关的 LibreOffices 无头模式。
我的 Spring Web 应用程序生成一个 ODT,将其导出为 PDF 文件并通过 HTTP 将其发送回用户。
会发生什么
-
生成 ODT
执行 LibreOffice 无头模式(转换为 pdf)
发送给用户
两个和三个几乎同时发生,导致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"
【问题讨论】:
【参考方案1】:如果外部进程确实通过终止表明它已经结束,那么你可以使用Process.waitFor()
。
如果外部进程可能挂起(并且您不希望您的 java 应用程序卡住),则使用带有参数的 Process.waitFor(...)
的变体来指定超时。
如果外部进程将不返回(例如,因为它是一个长期运行的服务,不会分离...),或者如果它可能返回之前已创建所需的输出,然后变得更加困难:
简单的方法是轮询输出文件;例如致电File.exists()
。这是低效的,特别是如果您经常轮询和/或长时间轮询。 (但在很多情况下你可以忍受。)
一种更复杂的方法是使用 Java“文件观察器”机制在文件创建时获取通知。在大多数平台上,这比轮询更有效。
但是检查文件何时创建的问题是您(通常)不知道外部进程何时完成对文件的写入。如果它确实以块的形式写入文件,那么您需要实施某种启发式方法来检测这一点;例如在最后一次“文件更新”事件后等待 N 秒。
对于特定情况,您需要调查外部应用程序如何生成输出,并相应地选择您的 Java 应用程序“检查是否完成”策略/启发式。我希望像 LibreOffice 这样的东西“表现良好”。
相关问题:
Wait for process to finish before proceeding in Java【讨论】:
【参考方案2】:在 runtime.exec(...) 返回的 Process 对象上,你可以调用 waitFor() 方法让你的线程等待直到进程完成。
http://docs.oracle.com/javase/7/docs/api/java/lang/Process.html#waitFor()
【讨论】:
以上是关于等到 LibreOffice 创建文件的主要内容,如果未能解决你的问题,请参考以下文章
用于创建连接到现有电子表格“数据库”的 Libreoffice 数据库文件的 BASH 脚本
创建 libreoffice 基于文本的数据源并使用 java 设置设置
如何判断 .doc 是不是由 LibreOffice 创建?