检查文件是否已完全写入

发布于 2024-12-09 11:14:55 字数 350 浏览 0 评论 0原文

如果我从 java 执行该软件,我如何知道该软件是否已完成写入文件?例如,我使用输入文件 RawText 执行 geniatagger.exe,该输入文件将生成输出文件 TAGGEDTEXT.txt。当 geniatagger.exe 完成写入 TAGGEDTEXT.txt 文件时,我可以使用此文件做一些其他工作。问题是 - 我如何知道 geniatagger 已完成写入文本文件?

try{
  Runtime rt = Runtime.getRuntime();
    Process p = rt.exec("geniatagger.exe -i "+ RawText+ " -o TAGGEDTEXT.txt");
  }

How do I know if a software is done writing a file if I am executing that software from java?For example, I am executing geniatagger.exe with an input file RawText that will produce an output file TAGGEDTEXT.txt. When geniatagger.exe is finished writing the TAGGEDTEXT.txt file, I can do some other staffs with this file. The problem is- how can I know that geniatagger is finished writing the text file?

try{
  Runtime rt = Runtime.getRuntime();
    Process p = rt.exec("geniatagger.exe -i "+ RawText+ " -o TAGGEDTEXT.txt");
  }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

゛时过境迁 2024-12-16 11:14:55

你不能,或者至少不可靠。

在这种特殊情况下,您最好的选择是观看该过程完成。

作为奖励,您可以获得进程的返回代码,这可以告诉您是否发生了错误。

如果您实际上正在谈论这个 GENIA 标记器,下面是演示各种主题的实际示例(请参阅代码下方有关编号注释的说明)。该代码使用 Linux 版 v1.0 进行了测试,并演示了如何安全地运行一个期望输入和输出流管道正常工作的进程。

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.concurrent.Callable;

import org.apache.commons.io.IOUtils;

public class GeniaTagger {

    /**
     * @param args
     */
    public static void main(String[] args) {
        tagFile(new File("inputText.txt"), new File("outputText.txt"));
    }

    public static void tagFile(File input, File output) {
        FileInputStream ifs = null;
        FileOutputStream ofs = null;
        try {
            ifs = new FileInputStream(input);
            ofs = new FileOutputStream(output);
            final FileInputStream ifsRef = ifs;
            final FileOutputStream ofsRef = ofs;

            // {1}    
            ProcessBuilder pb = new ProcessBuilder("geniatagger.exe");
            final Process pr = pb.start();

            // {2}
            runInThread(new Callable<Void>() {
                public Void call() throws Exception {
                    IOUtils.copy(ifsRef, pr.getOutputStream());
                    IOUtils.closeQuietly(pr.getOutputStream());   // {3}
                    return null;
                }
            });
            runInThread(new Callable<Void>() {
                public Void call() throws Exception {
                    IOUtils.copy(pr.getInputStream(), ofsRef);   // {4}
                    return null;
                }
            });
            runInThread(new Callable<Void>() {
                public Void call() throws Exception {
                    IOUtils.copy(pr.getErrorStream(), System.err);
                    return null;
                }
            });

            // {5}
            pr.waitFor();
            // output file is written at this point.
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // {6}
            IOUtils.closeQuietly(ifs);
            IOUtils.closeQuietly(ofs);
        }
    }

    public static void runInThread(final Callable<?> c) {
        new Thread() {
            public void run() {
                try {
                    c.call();
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                }
            }
        }.start();
    }
}
  1. 使用ProcessBuilder来启动您的进程,它比普通的Runtime.getRuntime().exec(...)有更好的界面。

  2. 在不同的线程中设置流管道,否则 ({5}) 中的 waitFor() 调用可能永远无法完成。

  3. 请注意,我通过管道将 FileInputStream 传送到了该进程。根据上述 GENIA 页面,该命令需要实际输入而不是 -i 参数。连接到进程的 OutputStream 必须关闭,否则程序将继续运行!

  4. 将处理结果复制到 FileOutputStream,即您正在等待的结果文件。

  5. 让主线程等待,直到进程完成。

  6. 清理所有流。

You can't, or at least not reliably.

In this particular case your best bet is to watch the Process complete.

You get the process' return code as a bonus, this could tell you if an error occurred.

If you are actually talking about this GENIA tagger, below is a practical example which demonstrates various topics (see explanation about numbered comments beneath the code). The code was tested with v1.0 for Linux and demonstrates how to safely run a process which expects both input and output stream piping to work correctly.

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.concurrent.Callable;

import org.apache.commons.io.IOUtils;

public class GeniaTagger {

    /**
     * @param args
     */
    public static void main(String[] args) {
        tagFile(new File("inputText.txt"), new File("outputText.txt"));
    }

    public static void tagFile(File input, File output) {
        FileInputStream ifs = null;
        FileOutputStream ofs = null;
        try {
            ifs = new FileInputStream(input);
            ofs = new FileOutputStream(output);
            final FileInputStream ifsRef = ifs;
            final FileOutputStream ofsRef = ofs;

            // {1}    
            ProcessBuilder pb = new ProcessBuilder("geniatagger.exe");
            final Process pr = pb.start();

            // {2}
            runInThread(new Callable<Void>() {
                public Void call() throws Exception {
                    IOUtils.copy(ifsRef, pr.getOutputStream());
                    IOUtils.closeQuietly(pr.getOutputStream());   // {3}
                    return null;
                }
            });
            runInThread(new Callable<Void>() {
                public Void call() throws Exception {
                    IOUtils.copy(pr.getInputStream(), ofsRef);   // {4}
                    return null;
                }
            });
            runInThread(new Callable<Void>() {
                public Void call() throws Exception {
                    IOUtils.copy(pr.getErrorStream(), System.err);
                    return null;
                }
            });

            // {5}
            pr.waitFor();
            // output file is written at this point.
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // {6}
            IOUtils.closeQuietly(ifs);
            IOUtils.closeQuietly(ofs);
        }
    }

    public static void runInThread(final Callable<?> c) {
        new Thread() {
            public void run() {
                try {
                    c.call();
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                }
            }
        }.start();
    }
}
  1. Use a ProcessBuilder to start your process, it has a better interface than plain-old Runtime.getRuntime().exec(...).

  2. Set up stream piping in different threads, otherwhise the waitFor() call in ({5}) might never complete.

  3. Note that I piped a FileInputStream to the process. According to the afore-mentioned GENIA page, this command expects actual input instead of a -i parameter. The OutputStream which connects to the process must be closed, otherwhise the program will keep running!

  4. Copy the result of the process to a FileOutputStream, the result file your are waiting for.

  5. Let the main thread wait until the process completes.

  6. Clean up all streams.

七色彩虹 2024-12-16 11:14:55

如果程序在生成输出文件后退出,则可以调用 Process.waitFor() 让它运行完成,然后您就可以处理文件了。请注意,您可能必须耗尽标准输出和错误流(至少在 Windows 上)才能完成该过程。

[编辑]

这是一个示例,未经测试且可能存在问题:

  // ...
  Process p = rt.exec("geniatagger.exe -i "+ RawText+ " -o TAGGEDTEXT.txt");
  drain(p.getInputStream());
  drain(p.getErrorStream());
  int exitCode = p.waitFor();
  // Now you should be able to process the output file.
}

private static void drain(InputStream in) throws IOException {
  while (in.read() != -1);
}

If the program exits after generating the output file then you can call Process.waitFor() to let it run to completion then you can process the file. Note that you will likely have to drain both the standard output and error streams (at least on Windows) for the process to finish.

[Edit]

Here is an example, untested and likely fraught with problems:

  // ...
  Process p = rt.exec("geniatagger.exe -i "+ RawText+ " -o TAGGEDTEXT.txt");
  drain(p.getInputStream());
  drain(p.getErrorStream());
  int exitCode = p.waitFor();
  // Now you should be able to process the output file.
}

private static void drain(InputStream in) throws IOException {
  while (in.read() != -1);
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文