我正在学习java PipedInputStream / PipeOutputStream。
我想阅读标准输入(下面的'来源'类)并将其重定向到进程(此处为'grep A'), Grep 的输出将被重定向到System.out。
为了在grep之后完成stdout和stderr,我还创建了一个类 CopyTo 来将输入流重定向到输出流。
import java.io.*;
class Test
{
private static class Source
implements Runnable
{
private PipedOutputStream pipedOutputStream=new PipedOutputStream();
private InputStream in;
Source(InputStream in) throws IOException
{
this.in=in;
}
@Override
public void run()
{
try
{
int c;
while((c=this.in.read())!=-1)
{
pipedOutputStream.write(c);
}
pipedOutputStream.flush();
pipedOutputStream.close();
}
catch(Exception err)
{
err.printStackTrace();
}
}
}
private static class Grep
implements Runnable
{
private PipedInputStream pipeInPipedInputStream;
public Grep(Source src) throws IOException
{
this.pipeInPipedInputStream=new PipedInputStream(src.pipedOutputStream);
}
@Override
public void run()
{
try {
Process proc=Runtime.getRuntime().exec(new String[]{
"/bin/grep",
"A"});
OutputStream os=proc.getOutputStream();
Thread t1=new Thread(new CopyTo(proc.getErrorStream(),System.err));
Thread t2=new Thread(new CopyTo(proc.getInputStream(),System.out));
t1.start();
t2.start();
int c;
while((c=this.pipeInPipedInputStream.read())!=-1)
{
os.write((char)c);
}
t1.join();
t2.join();
}
catch (Exception e) {
e.printStackTrace();
}
}
}
private static class CopyTo implements Runnable
{
private InputStream in;
private OutputStream out;
CopyTo(InputStream in,OutputStream out)
{
this.in=in;
this.out=out;
}
@Override
public void run() {
try {
int c;
while((c=in.read())!=-1)
{
out.write(c);
}
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
public static void main(String[] args)
{
try
{
Source src=new Source(System.in);
Thread t1=new Thread(src);
Thread t2=new Thread(new Grep(src));
t1.start();
t2.start();
}
catch(Exception err)
{
err.printStackTrace();
}
}
}
但是,编译和运行程序不会产生任何输出(程序被冻结)。
$ javac Test.java && echo -e "A\nT\nG\nC" | java Test
我哪里错了?感谢。
答案 0 :(得分:1)
您需要在代码块之后刷新并关闭Grep类的方法run()中的os流:
while((c=this.pipeInPipedInputStream.read())!=-1)
{
os.write((char)c);
}
添加以下行:
os.flush();
os.close();
Grep类的run()方法必须如下所示:
@Override
public void run()
{
try {
Process proc=Runtime.getRuntime().exec(new String[]{
"/bin/grep",
"A"});
OutputStream os=proc.getOutputStream();
Thread t1=new Thread(new CopyTo(proc.getErrorStream(),System.err));
Thread t2=new Thread(new CopyTo(proc.getInputStream(),System.out));
t1.start();
t2.start();
int c;
while((c=this.pipeInPipedInputStream.read())!=-1)
{
os.write((char)c);
}
//missing lines of code
os.flush();
os.close();
t1.join();
t2.join();
}
catch (Exception e) {
e.printStackTrace();
}
}
命令的输出:
$ javac Test.java && echo -e "A\nT\nG\nC" | java Test
将是:
A
程序将终止。