前几天用到了管道流,在使用的过程中又涉及到了流的重定向,在这里总结一下,还有一些问题不太明白,希望网友能点评一下。
网上说的重定向主要是LINUX里边,也有java标准流的重定向。都是把一个输入流定向到另一个输出流(个人感是输出流定向到另一个输入流,相对来说)。
下边的例子就是把程序的输出流重定向到一个文件(流)中。
importjava.io.*;
publicclassRedirect {
publicstaticvoidmain(String[] args)throwsIOException {
File f=newFile("out.txt");
f.createNewFile();
System.out.println("这句从控制台输出,不会输出到文件out.txt");
FileOutputStream fileOutputStream = newFileOutputStream(f);
PrintStream printStream = newPrintStream(fileOutputStream);
System.setOut(printStream);
System.out.println("默认输出到控制台的这一句,输出到了文件 out.txt");
}
}
下面是从网上找的一个例子。是把程序的输出内容重定向到GUI组件中。
importjava.io.OutputStream;
importjava.io.PrintStream;
importjavax.swing.SwingUtilities;
importjavax.swing.text.JTextComponent;
publicclassGUIPrintStreamextendsPrintStream {
privateJTextComponent component;
privateStringBuffer sb =newStringBuffer();
publicGUIPrintStream(OutputStream out, JTextComponent component) {
super(out);
this.component = component;
}
@Override
publicvoidwrite(byte[] buf,intoff,intlen) {
finalString message =newString(buf, off, len);
SwingUtilities.invokeLater(newRunnable() {
publicvoidrun() {
sb.append(message);
component.setText(sb.toString());
}
});
}
}
public class MainFrame extends javax.swing.JFrame {
private javax.swing.JButton btnOut;
private javax.swing.JScrollPane scrollPane;
private javax.swing.JTextArea textArea;
public MainFrame() {
initComponents();
// 重定向到通过文本组件构建的组件输出流中。
System.setOut(new GUIPrintStream(System.out, textArea));
}
private void initComponents() {
scrollPane=newjavax.swing.JScrollPane();
textArea=newjavax.swing.JTextArea();
btnOut=newjavax.swing.JButton();
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
setTitle("标准输出重定向到GUI - www.chenwei.mobi");
textArea.setColumns(20);
textArea.setRows(5);
scrollPane.setViewportView(textArea);
getContentPane().add(scrollPane, java.awt.BorderLayout.CENTER);
btnOut.setText("System.out.println(System.getProperties());");
btnOut.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
btnOutActionPerformed(evt);
}
});
getContentPane().add(btnOut, java.awt.BorderLayout.PAGE_END);
pack();
}
private void btnOutActionPerformed(java.awt.event.ActionEvent evt) {
System.out.println(System.getProperties());
}
public static void main(String args[]) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new MainFrame().setVisible(true);
}
});
}
}
这个例子相对上一个较复杂点儿,认真看一下也不难,就是把程序本应该输出到控制台的内容重定向到JTEXT里显示。
看完这两个例子,发觉重定向只是针对程序输出的内容(在JAVA里也就是System.out.println()的内容,当然还有System.err),如果把程序输出内容换成其们流比如,本来是把System.out.println("......")的内容定向到out.txt里,我现在有一个文件叫in.txt。我把他“重定向”到out.txt .大家这时就会觉得是什么样的呢?就是把一个流的传递。把in.txt当做out.txt的“参数”传给他。
个人感觉标流的重定向就是叫法上的不一样。大家有什么想法也说说。
下面我们看一下管道流,感觉里边渗杂着流的重定向。
import java.io.IOException;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;
class Send implements Runnable {
// 实现Runnable接口
private PipedOutputStream pos=null; // 管道输出流
public Send() {
this.pos=newPipedOutputStream();// 实例化输出流
}
public void run() {
String str="Hello";
try {
this.pos.write(str.getBytes()); // 输出信息
} catch (IOException e) {
e.printStackTrace();
}
try {
this.pos.close(); // 关闭输出流
} catch (IOException e) {
e.printStackTrace();
}
}
public PipedOutputStream getPos() { // 通过线程类得到输出流
return pos;
}
}
class Receive implements Runnable { // 实现Runnable接口
private PipedInputStream pis=null;
public Receive() {
this.pis=newPipedInputStream(); // 实例化输入流
}
public void run() {
byte b[] = new byte[1024];
int len=0;
try {
len=this.pis.read(b); // 接收数据
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("接收的内容为:" + new String(b, 0, len));
try {
this.pis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public PipedInputStream getPis() {
return pis;
}
}
public class PipedDemo1 {
public static void main(String[] args) {
Send s=newSend();
Receive r=newReceive();
try {
s.getPos().connect(r.getPis()); // 连接管道
} catch (IOException e) {
e.printStackTrace();
}
new Thread(s).start(); // 启动线程
new Thread(r).start(); // 启动线程
}
这是一个简单的管道流的应用。是不是也是一个流的重定向(个人觉得是)。
下面这个例子是我在写程序时遇到的。
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
public class Test {
/**
* discripe
* parameter
* @param args
*/
public static void main(String[] args) throws Exception{
Runtime rt=Runtime.getRuntime();
Process process1=rt.exec("ps -aux");
Process process2=rt.exec("grep "+"root");
// Process process3=rt.exec("ps -aux|grep root");
InputStream is=null;
InputStreamReader isr=null;
BufferedReader buffer=null;
String line=null;
ArrayListlist=newArrayList();
// System.out.println("-------------------------------------------------------------");
// InputStream is1=process1.getInputStream();
// isr=newInputStreamReader(is1);
// buffer=newBufferedReader(isr);
// while((line=buffer.readLine())!=null){
// System.out.println(line);
// list.add(line);
// }
//
// System.out.println("-------------------------------------------------------------");
//
// InputStream is2=process2.getInputStream();
// isr=newInputStreamReader(is2);
// buffer=newBufferedReader(isr);
// while((line=buffer.readLine())!=null){
// System.out.println(line);
// list.add(line);
// }
// System.out.println("-------------------------------------------------------------");
is=Piper.pipe(process1,process2);
isr=newInputStreamReader(is);
buffer=newBufferedReader(isr);
while((line=buffer.readLine())!=null){
System.out.println(line);
list.add(line);
}
process1.destroy();
process2.destroy();
}
}
import java.io.InputStream;
import java.io.OutputStream;
public class Piper implements java.lang.Runnable {
private InputStream input;
private OutputStream output;
public Piper(InputStream input, OutputStream output) {
this.input= input;
this.output= output;
}
public void run() {
try {
// Create 512 bytes buffer
byte[] b=newbyte[512];
int read=1;
// As long as data is read; -1 means EOF
while (read >-1) {
// Read bytes into buffer
read=input.read(b, 0, b.length);
//System.out.println("read: " + new String(b));
if (read >-1) {
// Write bytes to output
output.write(b, 0, read);
}
}
} catch (Exception e) {
// Something happened while reading or writing streams; pipe is broken
throw new RuntimeException("Broken process", e);
} finally {
try {
input.close();
} catch (Exception e) {
}
try {
output.close();
} catch (Exception e) {
}
}
}
public static InputStream pipe(Process... proc) throws InterruptedException {
// Start Piper between all processes
Process p1;
Process p2;
for (int i=0; i
p1=proc[i];
// If there's one more process
if (i + 1
p2=proc[i + 1];
// Start piper
new Thread(new Piper(p1.getInputStream(), p2.getOutputStream())).start();
}
}
Process last=proc[proc.length - 1];
// Wait for last process in chain; may throw InterruptedException
last.waitFor();
// Return its InputStream
return last.getInputStream();
}
}
上面的这个例子如果直接用
Processprocess3=rt.exec("ps -aux|grep root");是会出错的,后来一往网友说点击打开链接如是。这个是我临时在那个社区里发的。
其实还是搞不明白process1的结果怎么传给process2,我不是说上边Piper类。在linux里ps -aux|grep root这句话是一个什么的执行机制。知道的网友说一下。不要说比如“ps -aux的结果传给grep root”这类的话,太笼统了,不明白。