【问题标题】:Identify if a ".prn file " is written completely in java确定“.prn 文件”是否完全用 java 编写
【发布时间】:2014-02-02 00:10:42
【问题描述】:

我正在尝试确定打印作业或 .prn 文件是否已完成写入计算机。 创建步骤:单击文件上的打印 -> 并选择(打印到文件) 将尝试将该文件保存在您计算机上的某个位置,并打开一个输入文件名和保存位置的窗口。 输入文件名,点击保存。

然后该文件将开始以 .prn 文件的形式写入指定文件夹。 我正在尝试确定此写入是否已完成以及该文件是否可用于进一步处理。 java - 如何识别文件是否完整并在java中准备就绪? 我尝试了文件锁定(nio)以及随机文件访问。后者在尝试从计算机上的一个位置保存/移动/复制到另一个位置时有效,但是当我尝试使用 .prn 保存时,失败了。

请建议在java中识别.prn文件写入是否完成。

下面是我试图找出 .prn 文件是否已完成写入文件夹的代码。 I have tried this, from this link here.

public void uploadFiles(final File folder) {
    if (folder.list().length > 0) {
         upload.setEnabled(true);
        for (final File fileEntry : folder.listFiles()) {
            try {
                if(isFileCompletelyWritten(fileEntry)){
                if (onSendData(fileEntry.getAbsolutePath())) {
                    deleteFile(fileEntry);
                }
            }
            }catch (Exception e) {
                e.printStackTrace();
            }
        }
    } else {
             upload.setEnabled(false);
    }
}

private boolean isFileCompletelyWritten(File file) {
    RandomAccessFile stream = null;
    try {
        stream = new RandomAccessFile(file, "rwd");  
        return true;
    } catch (Exception e) {
       System.out.println("Skipping file " + file.getName() + " for this iteration as it's not completely written");
    } finally {
        if (stream != null) {
            try {
                stream.close();
            } catch (IOException e) {
                 System.out.println("Exception during closing file " + file.getName());
            }
        }
    }
    return false;
}

isFileCompletelyWritten(文件文件)

方法是我添加的查找文件写入是否完成的方法。这在我尝试保存打印文件时不起作用,但在复制、移动、将文件从计算机上的一个文件夹保存到另一个文件夹时它确实起作用。 .prn 文件在字节流进入时可供我的程序使用。RandomfileAccess 无法检测写入是否完成,而不是跳过该文件。当字节流按顺序逐块写入文件时,我的程序继续执行下一步,认为文件是完整且可用的。当我在将本地文件从一个位置复制到另一个位置时运行相同的代码时,Randomfileaccess 能够检查并看到正在写入更多数据,并且我的程序能够跳过该迭代的过程。这就是我的程序失败的原因。

【问题讨论】:

  • 您需要解释(更清楚地)准确您尝试了什么以及准确什么失败了。你目前的解释太模糊了。
  • 谢谢。我添加了更多关于我尝试和失败的细节。请建议是否有办法确定 .prn 文件已完全写入。
  • 你还没有解释如何它失败了。
  • 用进一步的解释更新了我的问题。

标签: java file


【解决方案1】:

虽然我正在等待您更新您的问题,并详细说明您尝试了什么以及它是如何失败的......

AFAIK 唯一保证工作可靠且可移植的方法涉及编写打印文件的程序告诉其他程序完成后。

  • 如果你控制正在写入打印文件的程序,你可以修改它以在它完成时做一些事情。

  • 如果程序是(或可能)通过包装器启动的,您可以修改包装器。

  • 如果它是您从 Java 中exec 的外部程序,您可以使用Process.waitFor() 来测试它何时退出。

涉及锁定和检查文件更新时间戳的解决方案会遇到各种可移植性和可靠性问题。


Re:您当前的解决方案。您的“完全编写”测试实际上是在测试您是否可以打开文件。

  • 如果文件不存在(因为打印还没有开始!),这将创建一个空文件并说它已完成。错了!

  • 如果文件确实存在,则打开尝试可能会尝试锁定文件,但这取决于操作系统。 (在 Linux 上,除非所有涉及的程序都显式使用锁定,否则没有锁定。)

所以基本上,这在 Linux 上根本行不通。 (在 Windows 上,只要您在创建文件之前不对其进行测试,它就可以工作......这是一种“竞争条件”,至少在理论上,使解决方案不可靠。)


那么还有哪些其他选择?

  • 您可以轮询文件的最后修改日期或大小,以查看它/它们何时停止更改。在一段合适的(启发式!)不活动时间后,假设文件已完成。

  • 您可以使用 FileWatcherService 实现上述功能。 (完成启发式不活动期等)

  • 您可以尝试使用 Lock ...,但写入文件的程序可能没有使用锁(在 Linux 上)。 (Lock API 用于自主锁定,它依赖于所有涉及使用锁定的应用程序,无论是隐式还是显式。在 Linux / Unix 上,锁定不会隐式或默认发生。)

我要再次强调,这些替代方案中没有一个是可移植且完全可靠的。

【讨论】:

  • 打印文件是用户操作,所以我看不出有可能控制它。我剩下的选项是,以某种方式监视正在写入的文件(正在写入的文件夹位置是固定的),一旦完成,我可以进一步处理该文件。由于 .prn 是一个顺序文件,我不确定是否有办法找到确定文件是否已完全写入的方法。另外,我完全同意你关于文件锁不是一个好的选择。如果可能,请提供更多见解。随机文件访问方式在这里看起来是不可能的。
  • 我仍在等待您完成问题...并说明您当前尝试的解决方案如何失败。
  • 当字节流进入时,我的程序可以使用 .prn 文件。感谢跳过文件,RandomfileAccess 没有检测到写入是否完成。当字节流按顺序逐块写入文件时,我的程序继续执行下一步,认为文件已完成且可用。但是当我尝试将本地文件从一个位置复制到另一个位置时,Randomfileaccess 能够检查并看到正在写入更多数据,并且我的程序能够跳过该迭代的过程。这就是我的程序失败的原因。
  • 感谢您的回复。我在 Windows 平台上运行代码。在这里,如果文件不存在,则代码按预期工作。它不会创建新的空文件。 isFileCompletelyWritten 能够识别文件夹中不存在任何文件并且运行良好。是的,我正在尝试在这里打开文件,希望文件在未完全写入时无法打开。所以,我觉得这是一个可靠的逻辑来测试文件写入是否完成。但是,这不适用于打印到文件。
  • 我刚刚尝试了 Watcher 服务,它运行良好,正在监听新文件。但是,我遇到了同样的问题,我无法找到一种方法来查看打印到文件是否完整。 Watcher 能够识别文件夹中是否有新文件。
【解决方案2】:

显然,我最终选择了 Java 中的打印 API,并尝试了以下代码 - this link to see if the print job is complete. 该示例确实启动了打印作业并监视以报告它是否完成。 但是,这不适合我的要求,因为我不希望程序创建打印作业。相反,监控当前在打印机上的用户启动的打印。 在 Java Print API 中似乎没有我可以遇到的解决方法来完成此任务。非常感谢任何进一步的 cmets、建议或解决方案。

【讨论】:

    【解决方案3】:

    根据您的打印机驱动程序编写的页面描述语言 (PDL),您可能能够检查文件中的作业结束标记。

    如果是 PCL,那么您将寻找“\x1b%-12345X@PJL EOJ\n%-12345X”。

    对于 Postscript,请查找“%%EOF”或“\x04”(文本的 ascii 结尾,也可能在作业开始时出现)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-06-29
      • 2011-09-14
      • 1970-01-01
      • 2013-03-31
      • 2017-04-29
      • 1970-01-01
      相关资源
      最近更新 更多