使用java输入流将输入传递给bash脚本,并使用线程将bash脚本输出收集到java输出流

时间:2016-03-29 18:36:04

标签: java multithreading parallel-processing stream processbuilder

我正在尝试使用java输入流将输入传递给bash脚本,并使用两个不同的线程将bash脚本输出收集到java输出流。

我的bash脚本是:     #!/ bin / sh的     echo“在开始时添加”     同时阅读LINE;做        echo $ LINE     完成

我的Java代码是:

public class NewRedirector implements Runnable {

private static final int BULK_BUFFER_SIZE = 500000;
private static final int READ_BUFFER_SIZE = 250000;

private static final int OFFSET = 0;
private final OutputStream targetStream;
private final InputStream sourceStream;
private final boolean useChannel;

public NewRedirector(InputStream sourceStream , OutputStream targetStream, boolean useChannel) {
    this.sourceStream = sourceStream;
    this.targetStream = targetStream;
    this.useChannel = useChannel;
}

@Override
public void run() {
    byte[] readbyte = new byte[READ_BUFFER_SIZE];
    int dataSize = 0;
    try {
        if(targetStream instanceof FileOutputStream && useChannel) {
            FileChannel targetFC = ((FileOutputStream) targetStream).getChannel();
            try {
            if(sourceStream instanceof FileInputStream && useChannel) {
                FileChannel sourceFC = ((FileInputStream) sourceStream).getChannel();
                ByteBuffer bb = ByteBuffer.allocateDirect(BULK_BUFFER_SIZE);
                bb.clear();
                dataSize = 0;
                while ((dataSize = sourceFC.read(bb)) > 0) {
                    bb.flip();
                    while (bb.hasRemaining()) {
                        targetFC.write(bb);
                    }
                    bb.clear();
                }
            } else {
                ByteBuffer bb = ByteBuffer.allocateDirect(BULK_BUFFER_SIZE);
                dataSize = 0;
                while ((dataSize = sourceStream.read(readbyte)) > 0) {
                    if(BULK_BUFFER_SIZE > bb.position() + dataSize) {
                        bb.put(readbyte, OFFSET, dataSize);
                        continue;
                    } else {
                        bb.flip();
                        targetFC.write(bb);
                        bb.clear();
                    }
                    bb.put(readbyte, OFFSET, dataSize);
                }
                if(bb.position() > 0) {
                    bb.flip();
                    targetFC.write(bb);
                    bb.clear();
                }
            }
            } catch(IOException e) {
                System.out.println("Got Exception: " + e);
            } finally {
                if(targetFC != null && targetFC.isOpen()) {
                    targetFC.close();
                    targetFC = null;
                }
            }
        } else {
            BufferedOutputStream btarget = new BufferedOutputStream(targetStream);
            try {
            if (sourceStream instanceof FileInputStream && useChannel) {
                FileChannel sourceFC = ((FileInputStream) sourceStream).getChannel();
                ByteBuffer bb = ByteBuffer.allocateDirect(BULK_BUFFER_SIZE);
                bb.clear();
                dataSize = 0;
                while ((dataSize = sourceFC.read(bb)) > 0) {
                    bb.position(OFFSET);
                    bb.limit(dataSize);
                    while (bb.hasRemaining()) {
                        dataSize = Math.min(bb.remaining(), READ_BUFFER_SIZE);
                        bb.get(readbyte, OFFSET, dataSize);
                        btarget.write(readbyte, OFFSET, dataSize);
                    }
                    btarget.flush();
                    bb.clear();
                }
            } else {
                dataSize = 0;
                while ((dataSize = sourceStream.read(readbyte)) > 0) {
                    btarget.write(readbyte, OFFSET, dataSize);
                }
                btarget.flush();
            }
        } catch(IOException e) {
            System.out.println("Got Exception: " + e);
        } finally {
            if(btarget != null) {
                btarget.close();
                btarget = null;
            }
            }
        }
    } catch (IOException e) {
        System.out.println("Got Exception: " + e);
    }
}

}

public class NewProcessExecutor {

public static void main(String ... args) throws IOException, InterruptedException {
    NewProcessExecutor pe = new NewProcessExecutor();
    pe.startProcessinputfromstreamoutputtostreamintwothread();
}

private void startProcessinputfromstreamoutputtostreamintwothread()
        throws IOException, InterruptedException {
    String lscriptLocation = "/scratch/demo/RunScript/append.sh";

    File inFile = new File("/scratch/demo/Source/inFile");
    File outFile = new File("/scratch/demo/Source/outFile");

    ProcessBuilder processBuilder = new ProcessBuilder(lscriptLocation);
    /*processBuilder.redirectInput(Redirect.PIPE);
    processBuilder.redirectOutput(Redirect.PIPE);*/
    Process process = processBuilder.start();       

    if(Redirect.PIPE.file() == null && Redirect.PIPE.type() == Redirect.Type.PIPE) {
        System.out.println("IO connected over PIPE");
    }

    //startStreamRedirector(new FileInputStream(inFile), process.getOutputStream());
    startStreamRedirector(process.getInputStream(), new FileOutputStream(outFile));
    int exitvalue = process.waitFor();
    System.out.println("Exit value: " + exitvalue);

    if (exitvalue != 0) {
        System.out.println("Script execution failed with error: "
                + readErrorStream(process.getErrorStream()));
        return;
    } else {
        System.out.println("Script executed successfully, please see output file: " + outFile.getAbsolutePath());
    }
}

private String readErrorStream(InputStream errorStream) {
    StringBuilder sb = new StringBuilder();
    try (BufferedReader buffR = new BufferedReader(new InputStreamReader(
            errorStream))) {
        String line = null;
        while ((line = buffR.readLine()) != null) {
            sb.append(line);
        }
    } catch (IOException e) {
        System.out.println("Got Exception: " + e);
    }
    return sb.toString();
}

private void startStreamRedirector(InputStream inputStream, OutputStream outputStream) {
    new Thread(new NewRedirector(inputStream, outputStream, true)).start();

}

}

现在的问题是这段代码有时运行得很好,但有时会创建零大小的文件。

有人可以指出可能是什么问题吗? 根据我的信息默认重定向是PIPE所以希望我不需要设置重定向输入和输出到PIPE。

processBuilder.redirectInput(Redirect.PIPE)

0 个答案:

没有答案