使用java输入流将输入传递给bash脚本,并使用线程将bash脚本输出收集到java输出流
我试图使用java输入流将输入传递给bash脚本,并使用两个不同的线程将bash脚本输出收集到java输出流 我的bash脚本是: #!/垃圾箱/垃圾箱 echo“在开始时添加” 读行时;做 回音$线 完成 我的Java代码是:使用java输入流将输入传递给bash脚本,并使用线程将bash脚本输出收集到java输出流,java,multithreading,parallel-processing,stream,processbuilder,Java,Multithreading,Parallel Processing,Stream,Processbuilder,我试图使用java输入流将输入传递给bash脚本,并使用两个不同的线程将bash脚本输出收集到java输出流 我的bash脚本是: #!/垃圾箱/垃圾箱 echo“在开始时添加” 读行时;做 回音$线 完成 我的Java代码是: public class NewRedirector implements Runnable { private static final int BULK_BUFFER_SIZE = 500000; private static final int READ_BUF
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);
}
}
}
及
}
现在的问题是,这段代码有时运行得很好,但有时会创建零大小的文件
有人能指出问题所在吗?
根据我的信息,默认重定向是管道,所以希望我不需要将重定向输入和输出设置为管道
processBuilder.redirectInput(Redirect.PIPE)
在这两种情况下,退出代码==0吗?@Antoniossss在这两种情况下都是,那么很可能它与环境相关-可能外部脚本根本没有写入任何输出,可能它正在向stderr打印某些内容,并以0代码停止。对我来说很难说。作为我的最后一个想法,您可以尝试将stderr重定向到stdout,看看会发生什么happens@Antoniossss,实际上这段代码工作得很好,因为这里的输出收集器线程正在写入FileOutputStream,并且它只在这个线程中被关闭,所以即使在主线程执行结束后,底层流也可以正常工作。但在我的实际项目中,目标outputstream(在本例中为文件)可以是任何内容,并且主线程也可以关闭它。所以,每当主线程执行在收集器线程之前结束时,收集器线程就会发现流已经关闭。。。。谢谢你的帮助。。
processBuilder.redirectInput(Redirect.PIPE)