Process. getInputStream () 차단 문제
8403 단어 자바
자바 Api 에서 Process 에 대해 말 하 는 것 은:
ProcessBuilder. start () 와 Runtime. exec 방법 으로 이 컴퓨터 프로 세 스 를 만 들 고 Process 하위 클래스 의 인 스 턴 스 를 되 돌려 줍 니 다. 이 인 스 턴 스 는 프로 세 스 를 제어 하고 관련 정 보 를 얻 을 수 있 습 니 다.프로 세 스 클래스 는 프로 세 스 입력, 출력 실행, 프로 세 스 완료 대기, 프로 세 스 종료 상태 검사, 프로 세 스 를 없 애 는 방법 을 제공 합 니 다.
프로 세 스 를 만 드 는 방법 은 이 컴퓨터 플랫폼 의 특정 프로 세 스 를 잘 작 동 하지 못 할 수도 있 습 니 다. 예 를 들 어 이 컴퓨터 창 프로 세 스, 데 몬, Microsoft Windows 의 Win 16/DOS 프로 세 스, 셸 스 크 립 트 등 입 니 다.만 든 하위 프로 세 스 는 터미널 이나 콘 솔 이 없습니다.모든 표준 io (즉 stdin, stdout, stderr) 작업 은 세 개의 흐름 (getOutputStream (), getInputStream (), getErrorStream () 을 통 해 부모 프로 세 스 로 재 설정 합 니 다.부모 프로 세 스 는 이 흐름 을 사용 하여 하위 프로 세 스 의 입력 과 하위 프로 세 스에 서 출력 을 가 져 옵 니 다.일부 이 플랫폼 은 표준 입력 과 출력 흐름 에 만 제 한 된 버퍼 크기 를 제공 하기 때문에 읽 기 쓰기 서브 프로 세 스 의 출력 흐름 이나 입력 흐름 이 신속하게 실패 하면 서브 프로 세 스 가 막 히 고 심지어 잠 금 이 생 길 수 있 습 니 다.getOutputStream (), getInputStream (), getErrorStream () 에 대한 설명 에서 주의사항 이 있 습 니 다. 출력 흐름 과 오류 흐름 을 버퍼 링 하 는 것 은 좋 은 생각 입 니 다!응, 추상 적 이 야!
문 제 는 바로 여기에 있 습 니 다. Process. getInputStream () 과 Process. getErrorStream () 은 각각 Process 의 표준 출력 흐름 과 오류 흐름 을 되 돌려 줍 니 다. 두 흐름 이 잘못 처리 되면 버퍼 가 제때에 제거 되 지 않 고 가득 차 면 프로 세 스 가 막 힙 니 다. Process. destory () 를 호출 하 더 라 도 막 힌 하위 프로 세 스 를 없 앨 수 있 는 것 은 아 닙 니 다.
Process 의 출력 흐름 과 오류 흐름 을 동기 화하 여 처리 하려 고 시도 하면 반드시 효과 가 있 는 것 은 아 닙 니 다. 순서 실행 과정 에서 출력 흐름 과 오류 흐름 은 제때에 처리 되 지 못 합 니 다.해결 방안 은 두 가지 가 있다.
프로젝트 1: process 의 출력 흐름 과 오류 흐름 을 동시에 가 져 옵 니 다.
두 스 레 드 를 시작 하여 출력 흐름 과 오류 흐름 을 동시에 읽 고 처리 합 니 다. IDE 를 열기 가 귀 찮 습 니 다. 코드 를 대충 두 드 려 보 세 요. 오류 가 있 을 수 있 습 니 다. 다음 과 같 습 니 다.
호출 자:
class ProcessExecutor
{
private Process p;
private List outputList;
private List errorOutputList;
public ProcessExecutor(Process p) throws IOException
{
if(null == p)
{
throw new IOException("the provided Process is null");
}
this. p = p;
}
public List getOutputList()
{
return this. outputList;
}
public List getErrorOutputList()
{
return this.errorOutputList;
}
public int execute()
{
int rs = 0;
Thread outputThread = new ProcessOutputThread(this.p.getInputStream());
Thread errorOutputThread = new ProcessOutputThread(this.p.getErrorStream());
outputThread.start();
errorOutputThread.start();
rs = p.waitFor();
outputThread.join();
errorOutputThread.join();
this.outputList = outputThread.getOutputList();
this.errorOutputList = errorOutputThread.getOutputList();
return rs;
}
}
흐름 처리 스 레 드
class ProcessOutputThread extends Thread
{
private InputStream is;
private List outputList;
public ProcessOutputThread(InputStream is) throws IOException
{
if(null == is)
{
throw new IOException("the provided InputStream is null");
}
this. is = is;
this.outputList = new ArrayList();
}
public List getOutputList()
{
return this. outputList;
}
@Override
public void run()
{
InputStreamReader ir = null;
BufferedReader br = null;
try
{
ir = new InputStreamReader(this.is);
br = new BufferedReader(ir);
String output = null;
while(null != (output = br.readLine()))
{
print(output);
this.outputList.add(output);
}
}
catch(IOException e)
{
e.print();
}
finally
(
try
{
if(null != br)
{
br.close();
}
if(null != ir)
{
ir.close();
}
if(null != this.is)
{
this.is.close();
}
}
catch(IOException e)
{
e.print();
}
)
}
}
프로젝트 2: ProcessBuilder 의 redirect ErrorStream () 방법 으로 출력 흐름 과 오류 흐름 을 합 칩 니 다.(이 방법 은 검증 이 통과 되 지 않 았 습 니 다)
public int execute()
{
int rs = 0;
String[] cmds = {...};//command and arg
ProcessBuilder builder = new ProcessBuilder(cmds);
builder.redirectErrorStream(true);
Process process = builder.start();
BufferedReader br = new BufferedReader(new InputStreamReader(process.getInputStream()));
String output = null;
while (null != (readLine = br.readLine()))
{
print(output);
}
rs = process.waitFor();
return rs;
}
다음으로 전송:http://blog.csdn.net/dancen/article/details/7969328#
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Is Eclipse IDE dying?In 2014 the Eclipse IDE is the leading development environment for Java with a market share of approximately 65%. but ac...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.