什么是java流的重定向_java标准流重定向和管道

前几天用到了管道流,在使用的过程中又涉及到了流的重定向,在这里总结一下,还有一些问题不太明白,希望网友能点评一下。

网上说的重定向主要是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”这类的话,太笼统了,不明白。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值