자바에서 Linux pipe 처리
- Posted at 2007/03/20 10:25
- Filed under Program/JAVA
아래 자바에서의 grep 관련 String 처리 연산에서의 속도 저하 문제를 해결하기 위해 다양한 고민을 한 결과 해결방법이 두가지가 나왔다.
1. String 클래스를 사용하지 않고 byte 기반의 아주 빠른 메소드를 별도로 구현한다.
-> regular expression까지 처리할려다 보니 너무 어려워서 포기..
2. Linux의 grep 명령을 그대로 활용한다.
-> 이 방법이 손쉬울 것 같아 채택.
2번 방법을 구현하기 위해서는 자바 Process 내에서 grep과 같은 Linux process를 실행시킨 다음 해당 process의 입력으로 자바 프로세스에서 값을 던져주고 Linux Process의 결과를 받아서 다시 처리하도록 구현하면 된다.
이런 구성이면 Linux의 다양한 pipe 명령문을 자바 Process에서 fork 한 다음 입력 값만 자바 프로그램을 통해 넣어주고 pipe의 결과를 다시 자바 프로그램에서 활용하는 방식으로도 구현이 가능하다.
다음과 같이 실행할 수 있다. 테스트 입력 값은 이 프로그램의 소스인 ProcessPipeTest.java를 이용했다.
ProcessPipeTest.java 파일에 "out" 문자가 들어 있는 라인을 찾아 알파벳 순으로 정렬하는 기능을 수행한다.
1. String 클래스를 사용하지 않고 byte 기반의 아주 빠른 메소드를 별도로 구현한다.
-> regular expression까지 처리할려다 보니 너무 어려워서 포기..
2. Linux의 grep 명령을 그대로 활용한다.
-> 이 방법이 손쉬울 것 같아 채택.
2번 방법을 구현하기 위해서는 자바 Process 내에서 grep과 같은 Linux process를 실행시킨 다음 해당 process의 입력으로 자바 프로세스에서 값을 던져주고 Linux Process의 결과를 받아서 다시 처리하도록 구현하면 된다.
이런 구성이면 Linux의 다양한 pipe 명령문을 자바 Process에서 fork 한 다음 입력 값만 자바 프로그램을 통해 넣어주고 pipe의 결과를 다시 자바 프로그램에서 활용하는 방식으로도 구현이 가능하다.
package kr.co.jaso;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.io.OutputStream;
public class ProcessPipeTest {
static class InputThread extends Thread {
Process process;
boolean end = false;
String fileName;
public InputThread(Process process, String fileName) {
this.process = process;
this.fileName = fileName;
}
public void run() {
BufferedInputStream fileIn = null;
try {
fileIn = new BufferedInputStream(new FileInputStream(fileName));
} catch (FileNotFoundException e1) {
end = true;
return;
}
OutputStream out = process.getOutputStream();
BufferedOutputStream bout = new BufferedOutputStream(out);
try {
int byteReads = 0;
byte[] buf = new byte[1024];
while ((byteReads = fileIn.read(buf)) > 0) {
bout.write(buf, 0, byteReads);
bout.flush();
}
bout.flush();
bout.close();
fileIn.close();
} catch (Exception e) {
e.printStackTrace();
}
end = true;
}
public boolean isEnd() {
return end;
}
}
static class ResultThread extends Thread {
BufferedInputStream in;
boolean end = false;
public ResultThread(InputStream in) {
this.in = new BufferedInputStream(in);
}
public void run() {
byte[] buf = new byte[1024];
int byteReads = 0;
try {
while ((byteReads = in.read(buf)) > 0) {
System.out.write(buf, 0, byteReads);
}
in.close();
} catch (Exception e) {
e.printStackTrace();
}
end = true;
}
public boolean isEnd() {
return end;
}
}
public static void main(String[] args) throws Exception {
if(args.length < 2) {
System.out.println("Usage: java ProcessPipeTest [input file] [pipe command]");
System.out.println(" java ProcessPipeTest /home/babokim/data/test.dat \"grep test | sort\"");
return;
}
String[] params = new String[3];
params[0] = "sh";
params[1] = "-c";
params[2] = args[1];
Process process = Runtime.getRuntime().exec(params);
InputThread inputThread = new InputThread(process, args[0]);
inputThread.start();
ResultThread resultThread = new ResultThread(process.getInputStream());
resultThread.start();
while (true) {
if (inputThread.isEnd() && resultThread.isEnd()) {
break;
} else {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
다음과 같이 실행할 수 있다. 테스트 입력 값은 이 프로그램의 소스인 ProcessPipeTest.java를 이용했다.
ProcessPipeTest.java 파일에 "out" 문자가 들어 있는 라인을 찾아 알파벳 순으로 정렬하는 기능을 수행한다.
java ProcessPipeTest /home/babokim/ProcessPipeTest.java "grep out | sort"
Posted by 김형준
- Response
- No Trackback , No Comment
Trackback URL : http://www.jaso.co.kr/trackback/146






