2012-07-04 6 views
4

Java 프로그램에서 외부 프로그램을 실행하려고하는데 문제가 있습니다. 기본적으로 나는이 될 것이다 이렇게하고 싶은 무엇을 : 그 작동하지 않는 것으로 나타났습니다 그러나Java에서 stdin 및 stdout 방향 전환 된 외부 프로그램 실행

Runtime.getRuntime().exec("./extprogram <fileIn >fileOut"); 

- 자바는 입력 및 출력 스트림과 난 다른 것들과 함께 Process를 사용하는 요구를 apparentls 경험이 없다.

나는 인터넷을 통해 많은 예를 보았으며 (그 중 많은 부분이 SO에서 왔음) 완전히 이해하지 못하는 사람을위한 간단한 표준 방식이 아닌 것 같습니다. 무슨 일이 일어나고 있는지, 상당히 좌절 할 수 있습니다.

다른 사람들의 코드 예제에서 일반적으로 보이는 코드를 빌드하는 데 문제가 있습니다. stdin 및 2를 리디렉션하는 데 관심이 없습니다. stdout으로 리디렉션하지 않아도됩니다. 파일 대신에 System.out.

외부 프로그램을 호출하고 stdinstdout을 리디렉션하기위한 좋은 간단한 코드 템플릿의 방향을 알려줄 수 있습니까? 감사.

답변

5

을, 같은 무언가가 작동합니다 :

public static void pipeStream(InputStream input, OutputStream output) 
    throws IOException 
{ 
    byte buffer[] = new byte[1024]; 
    int numRead = 0; 

    do 
    { 
     numRead = input.read(buffer); 
     output.write(buffer, 0, numRead); 
    } while (input.available() > 0); 

    output.flush(); 
} 

public static void main(String[] argv) 
{ 
    FileInputStream fileIn = null; 
    FileOutputStream fileOut = null; 

    OutputStream procIn = null; 
    InputStream procOut = null; 

    try 
    { 
     fileIn = new FileInputStream("test.txt"); 
     fileOut = new FileOutputStream("testOut.txt"); 

     Process process = Runtime.getRuntime().exec ("/bin/cat"); 
     procIn = process.getOutputStream(); 
     procOut = process.getInputStream(); 

     pipeStream(fileIn, procIn); 
     pipeStream(procOut, fileOut); 
    } 
    catch (IOException ioe) 
    { 
     System.out.println(ioe); 
    } 
} 

참고 :

  • close에 확인 스트림
  • 이것을 버퍼링 된 스트림을 사용하도록 변경하면, 원시 Input/OutputStreams 구현이 한 번에 한 바이트 씩 복사 할 수 있다고 생각합니다.
  • 프로세스의 처리는 아마도 특정 프로세스에 따라 달라질 수 있습니다. cat은 파이프 된 입출력에서 가장 간단한 예입니다.
+0

이 코드에 대해 마지막으로 한 가지 문제가 있습니다. 프로그램이 완료되면 파일이 비어 있습니다 (이미 데이터가 저장되어 있습니다). - 프로그램에서 사용중이었습니다.) 왜 그럴까요? – MattS

+0

MattS : 코드를 약간 업데이트했습니다. 이전 스트림 처리에는 몇 가지 문제가있었습니다 (스트림 처리에 대해 충분히 고려하지 않았습니다). 이러한 변경이 도움이 될 수 있습니다. 또한 몇 가지 메모를 추가했습니다. – pb2q

+0

@ pb1q 좋아요, 조금만 살펴 보겠습니다. 이전과 마찬가지로 코드를 사용하여 입/출력 스트림을 닫는 것을 기억했지만 프로세스의 오류 스트림을 닫는 것을 잊었습니다. 너무 많은 파일이 동시에 열리기 때문에 충돌이 발생했습니다. 다시 한번 감사드립니다. – MattS

8

당신은이 같은 시도 할 수 있습니다 : 당신이 Process를 사용해야하는 경우

ProcessBuilder pb = new ProcessBuilder(); 
pb.redirectInput(new FileInputStream(new File(infile)); 
pb.redirectOutput(new FileOutputStream(new File(outfile)); 
pb.command(cmd); 
pb.start().waitFor(); 
+2

1+하지만 'bp.redirectErrorStream (true)'을 호출하여 프로세스의 InputStream으로 폴드 할 수있는 오류 스트림을 잊지 마십시오. –

+0

'ProcessBuilder'는'redirectInput()'또는'redirectOutput()'함수를 가지고 있지 않습니다. http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/ProcessBuilder.html – MattS

+0

@MattS \ s \ 1.5.0 \ 7 http://docs.oracle.com/javase/ 7/docs/api/java/lang/ProcessBuilder.html – corsiKa

0

System.setIn 및 System.setOut을 사용해 보셨습니까? JDK 1.0부터 주변에있다.

public class MyClass 
{ 
    System.setIn(new FileInputStream("fileIn.txt")); 
    int oneByte = (char) System.in.read(); 
    ... 

    System.setOut(new FileOutputStream("fileOut.txt")); 
    ... 
관련 문제