乘风原创程序

  • Java通过Process执行C# exe程序
  • 2021/2/23 10:05:19
  • 一、前言

    最近在开发的时候,遇到java调用C#exe程序的时候,通过Process执行,一般C#程序都有日志输出,但是通过Java怎么获取呢?这其中又会遇到一些什么问题呢?

    想通过C#小程序上传文件到服务器,通过Process执行exe文件,但是上传成功与否,要通过小程序的日志来分析,但怎么获取日志呢?百度了一下,通过字符型输入流就可以,虽然功能实现了,但不知道为什么?

    public static boolean uploadFileByFtp(String path) {
        try {
            Process pro = Runtime.getRuntime().exec("cmd /c " + "D:\\tool\\uploadFileByFtp.exe" + " " + path);
            BufferedReader br = new BufferedReader(new InputStreamReader(pro.getInputStream()));
            String line = null;
            String ret = "";
            while ((line = br.readLine()) != null) {
                ret = ret + line + "\n";
            }
            if (ret.toString().contains("success")) {
                return true;
            } else {
                return false;
            }
        } catch (Exception e) {
            log.error("uploadFileByFtp exception:{}", e);
        }
        return false;
    }

    虽然功能实现了,但感觉缺少点什么?

    二、waitFor()

    waitFor()函数表示,等待子进程执行结束,或者已手动终止子进程,此方法立即返回,否则出于阻塞状态。

    当RunTime对象调用exec方法后,jvm会创建一个子进程,该子进程与jvm建立三个管道连接:标准输入流、标准输出流、标准错误流。假设该子进程不断向标准输入流、标准输出流写数据,而jvm不读取的话,会导致缓冲区塞满而无法继续写数据,最终堵塞在waitFor这里。

    问题的关键就是,将缓冲区中的信息读出来,便可以避免线程阻塞问题。

    public static boolean uploadFileByFtp2() {
        try {
            String path = "D:tool\\uploadFileByFtp\\log.txt";
            File filePath = new File(path);
    
            Process pro = Runtime.getRuntime().exec("cmd /c " + "D:\\tool\\uploadFileByFtp.exe" + " " + path);
    
            pro.waitFor();
    
            List<String> logs = FileUtils.readLines(new File(path), "UTF-8");
            // 获取最后一行 验证是取得成功
            String str = logs.get(logs.size() - 1);
            if (str.contains("success")) {
                log.info("uploadFileByFtp success");
                return true;
            } else {
                log.warn("uploadFileByFtp fail.");
                return false;
            }
        } catch (Exception e) {
            log.error("uploadFileByFtp exception:{}", e);
            return false;
        }
    }

    还有一种是获取cmd下的日志,

    public static boolean uploadFileByFtp3() {
        Process pro = Runtime.getRuntime().exec("cmd /c " + "D:\\tool\\uploadFileByFtp.exe" + " " + path);
     
        // 标准输入流(必须写在 waitFor 之前)
        String inStr = readInputStream(proc.getInputStream());
        // 标准错误流(必须写在 waitFor 之前)
        String errStr = readInputStream(proc.getErrorStream());
     
        int retCode = proc.waitFor();
        if(retCode == 0){
            System.out.println("文件上传成功");
        }
    }
     
    /**
    *   读取缓冲流inputstream,并返回
    */
    public static String readInputStream(InputStream is){
        BufferedReader br = new BufferedReader(new InputStreamReader(is));
        String s ;
        StringBuilder sb = new StringBuilder();
        while((s=br.readLine())!=null){
            System.out.println(s);
            sb.append(s);
        }
        return sb.toString();
    }

    ?

    往期精彩内容:

    Java知识体系总结(2021版)

    Java多线程基础知识总结(绝对经典)

    【全栈最全Java框架总结】SSH、SSM、Springboot

    超详细的springBoot学习笔记

    常见数据结构与算法整理总结

    Java设计模式:23种设计模式全面解析(超级详细)

    Java面试题总结(附答案)

    本文地址:https://blog.csdn.net/guorui_java/article/details/114003267