Java process 的一些疑问 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
Sign Up Now
For Existing Member  Sign In
rqxiao
V2EX    Java

Java process 的一些疑问

  •  
  •   rqxiao Dec 15, 2022 2319 views
    This topic created in 1231 days ago, the information mentioned may be changed or developed.
    import java.io.IOException; public class Test { public static void main(String[] args) throws IOException, InterruptedException { String command1 = "java -version"; String command2="/Users/user1/develop/ffmpeg/ffmpeg -i /Users/user1/develop/ffmpeg/input.avi -vflpossa fps=1/5 /Users/user1/develop/ffmpeg/input.avi.%d.jpg"; Process p=Runtime.getRuntime().exec(command1); ProcessHandler.dealStream(p); p.waitFor(); System.out.println("结束了"); } } 
    import lombok.extern.slf4j.Slf4j; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; /** * ref: https://blog.csdn.net/weixin_33690367/article/details/86134029 */ @Slf4j public class ProcessHandler { public static String dealStream(Process process) { StringBuilder builder = new StringBuilder(); if (process == null) { return null; } // 处理 InputStream 的线程 new Thread(() -> { BufferedReader in = new BufferedReader(new InputStreamReader(process.getInputStream())); String line; try { while ((line = in.readLine()) = null) { builder.append(line); log.info("input===: " + line); } } catch (IOException e) { e.printStackTrace(); } finally { try { in.close(); } catch (IOException e) { // TODO 处理出错 e.printStackTrace(); } } }).start(); // 处理 ErrorStream 的线程 new Thread(() -> { BufferedReader err = new BufferedReader(new InputStreamReader(process.getErrorStream())); String line; try { while ((line = err.readLine()) != null) { builder.append(line); log.info("错误---: " + line); } } catch (IOException e) { e.printStackTrace(); } finally { try { err.close(); } catch (IOException e) { // TODO 处理出错 e.printStackTrace(); } } }).start(); return builder.toString(); } } 

    1 )为啥 process 一些正常的输出都在 errorStream 里?现在有一个需求想用 ffmpeg 执行转码,如果转码出错了,是不是应该读取 标准错误输出流里 errorStream 的内容,如果 errorStream 的 StringBuilder 不为空,或者有 'error; 字符串,就可以认为是转码失败了?但现在输出测试下来怎么都在 errorstream 里。。

    结束了 14:04:19.433 [Thread-1] INFO com.utils.ProcessHandler - 错误---: java version "1.8.0_291" 14:04:19.436 [Thread-1] INFO com.utils.ProcessHandler - 错误---: Java(TM) SE Runtime Environment (build 1.8.0_291-b10) 14:04:19.436 [Thread-1] INFO com.utils.ProcessHandler - 错误---: Java HotSpot(TM) 64-Bit Server VM (build 25.291-b10, mixed mode) 

    2 ) process 机制原因会导致死锁,所以需要在 waitfor 方法之前,创建线程用于处理 inputstream 中缓冲区的数据。 不用其他线程清空 process 的缓冲区可以吗。在 process 开始后,单靠主线程读取缓冲的内容,读完了主线程再 waitfor 不可以吗。

    11 replies    2022-12-16 00:53:58 +08:00
    xiaohundun
        1
    xiaohundun  
       Dec 15, 2022
    可能是 java -version 这个命令行的问题吧,你试试其他的呢? 比如 ls -l /
    rqxiao
        2
    rqxiao  
    OP
       Dec 15, 2022
    @xiaohundun ls -l / 是 inputStream 。。。这是什么道理
    edsion996
        3
    edsion996  
       Dec 15, 2022   1
    wolfie
        4
    wolfie  
       Dec 15, 2022   1
    redirectErrorStream 合并流,然后用 exitValue 判断成功?
    xiaohundun
        5
    xiaohundun  
       Dec 15, 2022
    @rqxiao 不知道哎有没有可能源码就写错了给输出到标准错误输出里了
    ysc3839
        6
    ysc3839  
       Dec 15, 2022
    感觉是 X-Y Problem https://coolshell.cn/articles/10804.html
    你要调用 ffmpeg 的话可以看看 https://github.com/bramp/ffmpeg-cli-wrapper
    xiaohundun
        7
    xiaohundun  
       Dec 15, 2022   1
    @rqxiao 仔细看了下 java -h ,发现人家写的很清楚,-version 就是输出到错误流
    xiaohundun
        8
    xiaohundun  
       Dec 15, 2022
    @rqxiao 你可以用 java --version
    superliy
        9
    superliy  
       Dec 15, 2022
    一个线程一个 process ,你用 ffmpeg 转码,多个线程对你没啥影响
    superliy
        10
    superliy  
       Dec 15, 2022   1
    ProcessBuilder pb = new ProcessBuilder(generateExecCommand(execCommand.apply(args)));
    pb.redirectErrorStream(true);
    try {
    this.process = pb.start();
    BufferedReader stdOut = new BufferedReader(new InputStreamReader(process.getInputStream()));
    stdOut.lines().forEach(line -> log.info("{}#{}", name, line));
    } catch (IOException e) {
    log.error("Failed to start process: ", e);
    }
    wangyu17455
        11
    wangyu17455  
       Dec 16, 2022   1
    为了不污染 stdout ,很多非格式化输出都是输出到 stderr ,比如 curl 的实时进度就是输出到 stderr
    About     Help     Advertise     Blog     API     FAQ     Solana     2825 Online   Highest 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 64ms UTC 15:23 PVG 23:23 LAX 08:23 JFK 11:23
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86