简体   繁体   English

为什么 Java 并行文件写入不起作用?

[英]Why Java parallel file writing is not working?

I am trying to write a script that will run a.exe program 4 times with different parameters.我正在尝试编写一个脚本,该脚本将使用不同的参数运行 a.exe 程序 4 次。 I created one thread for each.exe run.我为每个.exe 运行创建了一个线程。 Each thread will write an output file.每个线程都会写一个 output 文件。 My problem is that, it should write in parallel, but as you can you see on the screenshot below, the file write one after another.我的问题是,它应该并行写入,但正如您在下面的屏幕截图中看到的那样,文件一个接一个地写入。 How should this be resolved?这应该如何解决?

在此处输入图像描述

Here's the main method:下面是主要方法:

public static void main (String args[]) {
    ExecutorService executor = Executors.newFixedThreadPool(4);
    executor.execute(new RunnableReader("myprogram.exe", param1, outputFile1));
    executor.execute(new RunnableReader("myprogram.exe", param2, outputFile2));
    executor.execute(new RunnableReader("myprogram.exe", param3, outputFile3));
    executor.execute(new RunnableReader("myprogram.exe", param4, outputFile4));
    executor.shutdown();
}

Here's the runnable class:这是可运行的 class:

public class RunnableReader implements Runnable {
    private String program;
    private String param;
    String outputFile;

    public RunnableReader(String program, String param, String outputFile) {
        this.program = program;
        this.param = param;
        this.outputFile = outputFile;
    }

    @Override
    public void run() {
        try {
            ProcessBuilder pb = new ProcessBuilder(program, param);
            pb.redirectOutput(ProcessBuilder.Redirect.PIPE);
            pb.redirectErrorStream(true);
            Process proc = pb.start();
            InputStream stream = proc.getInputStream();
            BufferedReader reader = new BufferedReader(new InputStreamReader(stream));
            BufferedWriter writer = new BufferedWriter(new FileWriter(outputFile, true));
            for(String output; (output = reader.readLine()) != null) {
                writer.append(output);
                writer.append("\n");
            }
            writer.close();
            reader.close();
            stream.close();
  
        } catch(IOException e) {
            e.printStackTrace();
        }
    }
}

I haven't been able to test this myself and I don't know if it actually causes the execution to block.我自己无法对此进行测试,也不知道它是否真的会导致执行阻塞。 But for what it's worth I thought I should point out that your reading of the process' InputStream might be unnecessary.但是对于它的价值,我认为我应该指出您可能不需要阅读流程的InputStream

As stated by the Oracle docs ProcessBuilder.redirectOutput(ProcessBuilder.Redirect.PIPE) causes Process.getInputStream() to return the process' standard output.正如Oracle 文档所述, ProcessBuilder.redirectOutput(ProcessBuilder.Redirect.PIPE)导致Process.getInputStream()返回进程的标准 output。

With that in mind you could get rid of the entire for-loop and instead just do something like ProcessBuilder.redirectOutput(new File(outputFile)) so that your method instead looks like this考虑到这一点,您可以摆脱整个for-loop ,而只需执行类似ProcessBuilder.redirectOutput(new File(outputFile))的操作,以便您的方法看起来像这样

@Override
public void run() {
    try {
        ProcessBuilder pb = new ProcessBuilder(program, param);
        pb.redirectOutput(new File(outputFile));
        pb.redirectErrorStream(true);
        Process proc = pb.start();
    } catch(IOException e) {
        e.printStackTrace();
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM