我正在尝试使用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)