자바 프로 세 스 와 런 타임()의 사용 및 cmd 명령 호출 차단 솔 루 션
자바 가 cmd 를 호출 하여 bat 파일 을 실행 할 때 카드 가 죽 는 현상 이 발생 할 수 있 습 니 다.그 때 는 매우 혼 란 스 러 웠 습 니 다.나중에 자 료 를 찾 았 습 니 다.원래 이렇게 프로그램 을 호출 하고 프로 세 스 의 출력 흐름 을 가 져 왔 습 니 다.그러나 저 는 windows 에서 이러한 호출 을 수행 할 때 항상 while 에서 막 혔 습 니 다.그 결과 ffmpeg 프로그램 이 잠시 실 행 된 후에 다시 실행 되 지 않 았 습 니 다.공식 참고 문서 에서 볼 수 있 듯 이 이것 은 버퍼 의 문제 입 니 다.자바 프로 세 스 가 버퍼 에 기 록 된 내용 을 비우 지 않 았 기 때문에 ffmpeg 프로그램 이 계속 기다 리 고 있 습 니 다.
인터넷 에서 도 이런 문 제 를 많이 찾 았 지만 단독 스 레 드 로 통 제 를 하 는 것 을 말 했 습 니 다.저도 인터넷 이 말 하 는 방법 을 많이 시 도 했 지만 아무런 역할 을 하지 못 했 습 니 다.
getInputStream 의 버퍼 가 비 워 지지 않 았 다 고 생각 했 지만 문 제 는 버퍼 의 내용 이 비 워 지지 않 았 다 는 것 입 니 다.하지만 getInputStream 이 아 닌 getErrorStream 의 버퍼 입 니 다.이 문 제 는 해결 되 었 습 니 다.
따라서 자바 가 외부 프로그램 을 호출 하여 스 레 드 가 막 혔 을 때 두 스 레 드 를 사용 하여 process 에서 가 져 온 두 개의 입력 흐름 을 동시에 비 우 는 것 을 고려 할 수 있 습 니 다.다음 절 차 는 다음 과 같 습 니 다.
public String excuteBatFile(String file, boolean isCloseWindow)
{
String cmdCommand = null;
String res = null;
if(isCloseWindow)
{
cmdCommand = "cmd.exe /c " + file;
}else
{
cmdCommand = "cmd.exe /k " + file;
}
StringBuilder stringBuilder = new StringBuilder();
Process process = null;
try {
process = Runtime.getRuntime().exec(cmdCommand);
final InputStream is1 = process.getInputStream();
new Thread(new Runnable() {
public void run() {
BufferedReader bufferedReader = null;
String line = null;
try {
bufferedReader = new BufferedReader(
new InputStreamReader(is1, "GBK"));
while((line=bufferedReader.readLine()) != null)
{
stringBuilder.append(line+"
");
}
is1.close();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}).start(); // p.getInputStream()
InputStream is2 = process.getErrorStream();
BufferedReader br2 = new BufferedReader(new InputStreamReader(is2));
StringBuilder buf = new StringBuilder(); //
String line2 = null;
while((line2 = br2.readLine()) != null) buf.append(line2); //
log.info("----res:----" + stringBuilder + "&" + buf);
return stringBuilder + "&" + buf;
} catch (Exception e) {
e.printStackTrace();
return e.toString();
}
}
이 를 통 해 우 리 는 하나의 스 레 드 를 사용 하여 process.getInputStream()의 출력 흐름 을 읽 고 다른 스 레 드 를 사용 하여 process.getErrorStream()의 출력 흐름 을 가 져 옵 니 다.그러면 스 레 드 가 막 히 는 것 을 걱정 하지 않 고 버퍼 가 제때에 비 워 질 수 있 습 니 다.물론 필요 에 따라 process.getInputStream()흐름 의 내용 을 유지 할 수 있 습 니 다.이것 은 호출 된 프로그램의 처리 에 달 려 있 습 니 다.
자바 프로 세 스 cmd 명령 흐름 차단 처리
코드 는 다음 과 같 습 니 다:
public static void runCmd() {
Process process = null;
BufferedReader bufferedReader = null;
try {
Logger.getLogger(SystemService.class).info("============= =============");
process = Runtime.getRuntime().exec("cmd.exe /c shutdown -r -f -t 0");
bufferedReader = new BufferedReader(new InputStreamReader(new BufferedInputStream(process.getInputStream()), Charset.forName("GB2312")));
// ,
new StreamInformatonThread(process.getErrorStream(), "error").start();
String outStr;
while ((outStr = bufferedReader.readLine()) != null) {
Logger.getLogger(SystemService.class).info("readLine -------> : " + outStr);
}
Logger.getLogger(SystemService.class).info("============= =============");
} catch (IOException e) {
Logger.getLogger(SystemService.class).error("============= =============");
e.printStackTrace();
} finally {
if (process != null) {
process.destroy();
}
if (bufferedReader != null) {
try {
bufferedReader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
import java.io.*;
/**
* @Description:
* @Author: zhangwenchao
* @Date: 2019/7/9 11:35
*/
public class StreamInformatonThread extends Thread {
private InputStream is;
private String str;
private Logger logger = Logger.getLogger(StreamInformatonThread.class);
public StreamInformatonThread(InputStream is, String str) {
this.is = is;
this.str = str;
}
public void run() {
BufferedReader out = null;
try {
out = new BufferedReader(new InputStreamReader(is, "gbk"));
String line;
while ((line = out.readLine()) != null) {
if (str.equals("error")) {
logger.info("ErrorStream --------> :" +line);
} else {
logger.info("outLine ---------> :" + line);
}
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (out != null) {
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
이상 은 개인 적 인 경험 이 므 로 여러분 에 게 참고 가 되 기 를 바 랍 니 다.여러분 들 도 저 희 를 많이 응원 해 주시 기 바 랍 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
JPA + QueryDSL 계층형 댓글, 대댓글 구현(2)이번엔 전편에 이어서 계층형 댓글, 대댓글을 다시 리팩토링해볼 예정이다. 이전 게시글에서는 계층형 댓글, 대댓글을 구현은 되었지만 N+1 문제가 있었다. 이번에는 그 N+1 문제를 해결해 볼 것이다. 위의 로직은 이...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.