Java执行cmd命令启动进程

Java执行cmd命令启动进程

1.代码

  //execute command through java application
    public static void exeCmd(){
        Runtime rt = Runtime.getRuntime();
        try {
          Process process =  rt.exec("net start mysql");//start mysql service
          process.isAlive();//Tests whether the subprocess represented by this Process is alive.
            InputStream stderr = process.getInputStream();//得到进程的标准数据信息流
            //OutputStream stdout = process.getOutputStream();

            //将字节流转换成字符流 设置转换的字符流的编码方式是GB2312
            InputStreamReader isr = new InputStreamReader(stderr,"GB2312");

            BufferedReader br = new BufferedReader(isr);
            String line = br.readLine();
            System.out.println(line);
            
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

2.执行结果

在执行程序之前,先退出mysql服务

```sql
  C:\Users\Administrator>net stop mysql
mysql 服务正在停止..
mysql 服务已成功停止。
  • intellij 标准输出
mysql 服务正在启动 .

Process finished with exit code 0
  • mysql 服务状态
C:\Users\Administrator>mysql -u root -p
Enter password: ****
ERROR 2003 (HY000): Can't connect to MySQL server on 'localhost' (10061)

C:\Users\Administrator>mysql -u root -p
Enter password: ****
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.7.22 MySQL Community Server (GPL)

Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql>

3.代码优化

import org.slf4j.LoggerFactory;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;


public class StreamManage extends  Thread{
    private final org.slf4j.Logger logger = LoggerFactory.getLogger(this.getClass());
    InputStream inputStream;
    String type;

    //StreamManage的构造参数是InputStream类实例 => 实际上是Process实例的返回流
    public StreamManage(InputStream inputStream,String type){
        this.inputStream = inputStream;
        this.type = type;
    }
    public void run(){
        InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
        BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
        String line = null;
        try{
            while((line = bufferedReader.readLine())!=null){
                if (type.equals("Error")) {
                    logger.error(line);
                }else{
                    logger.debug(line);
                }
            }
        }catch (IOException e){
            e.printStackTrace();
        }
    }
}
 //execute bat command
    public static void exeBat(){
        String cmd = "G:\\testdb\\test.bat 1 2 3 4 5 6";
        Runtime rt = Runtime.getRuntime();
        try {
            Process process = rt.exec(cmd);

            //getErrorStream: Returns the input stream connected to the error output of the subprocess.
            //                返回一个输入流。【这个输入流是子进程的错误输出】
            //getInputStream: Returns the input stream connected to the normal output of the subprocess.
            //                返回一个输入流。【这个输入流是子进程的正常输出】
            StreamManage stdErr = new StreamManage(process.getErrorStream(), "error");
            StreamManage stdout = new StreamManage(process.getInputStream(), "output");

            stdErr.start();
            stdout.start();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

执行结果如下:

SLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in [jar:file:/E:/.m2/repository/ch/qos/logback/logback-classic/1.0.13/logback-classic-1.0.13.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [jar:file:/E:/.m2/repository/org/slf4j/slf4j-log4j12/1.7.6/slf4j-log4j12-1.7.6.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation.
SLF4J: Actual binding is of type [ch.qos.logback.classic.util.ContextSelectorStaticBinder]
22:32:46.289 [Thread-1] DEBUG Test.StreamManage - 
22:32:46.293 [Thread-1] DEBUG Test.StreamManage - E:\intellij_Project\MyScala>echo a = G:\testdb\test.bat  1>>1.txt 
22:32:46.293 [Thread-1] DEBUG Test.StreamManage - 
22:32:46.293 [Thread-1] DEBUG Test.StreamManage - E:\intellij_Project\MyScala>echo b = 1  1>>1.txt 
22:32:46.293 [Thread-1] DEBUG Test.StreamManage - 
22:32:46.293 [Thread-1] DEBUG Test.StreamManage - E:\intellij_Project\MyScala>echo c = 2  1>>1.txt 
22:32:46.293 [Thread-1] DEBUG Test.StreamManage - 
22:32:46.293 [Thread-1] DEBUG Test.StreamManage - E:\intellij_Project\MyScala>echo d = 3  1>>1.txt 
22:32:46.293 [Thread-1] DEBUG Test.StreamManage - 
22:32:46.293 [Thread-1] DEBUG Test.StreamManage - E:\intellij_Project\MyScala>echo e = 4  1>>1.txt 
22:32:46.293 [Thread-1] DEBUG Test.StreamManage - 
22:32:46.293 [Thread-1] DEBUG Test.StreamManage - E:\intellij_Project\MyScala>shift         
22:32:46.293 [Thread-1] DEBUG Test.StreamManage - 
22:32:46.293 [Thread-1] DEBUG Test.StreamManage - E:\intellij_Project\MyScala>echo f = 6  1>>1.txt 
22:32:46.293 [Thread-1] DEBUG Test.StreamManage - 
22:32:46.294 [Thread-1] DEBUG Test.StreamManage - E:\intellij_Project\MyScala>rem

如果修改test.bat脚本的内容,成如下:

echo a = %0 >> 1.txt
echo b = %1 >> 1.txt
echo c = %2 >> 1.txt
echo d = %3 >> 1.txt
echo e = %4 >> 1.txt
shift        
f = %5 
rem pause

再执行程序,得到如下的结果:

SLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in [jar:file:/E:/.m2/repository/ch/qos/logback/logback-classic/1.0.13/logback-classic-1.0.13.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [jar:file:/E:/.m2/repository/org/slf4j/slf4j-log4j12/1.7.6/slf4j-log4j12-1.7.6.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation.
SLF4J: Actual binding is of type [ch.qos.logback.classic.util.ContextSelectorStaticBinder]
22:38:48.663 [Thread-1] DEBUG Test.StreamManage - 
22:38:48.663 [Thread-0] DEBUG Test.StreamManage - 'f' 不是内部或外部命令,也不是可运行的程序
22:38:48.666 [Thread-1] DEBUG Test.StreamManage - E:\intellij_Project\MyScala>echo a = G:\testdb\test.bat  1>>1.txt 
22:38:48.666 [Thread-0] DEBUG Test.StreamManage - 或批处理文件。
22:38:48.666 [Thread-1] DEBUG Test.StreamManage - 
22:38:48.666 [Thread-1] DEBUG Test.StreamManage - E:\intellij_Project\MyScala>echo b =   1>>1.txt 
22:38:48.666 [Thread-1] DEBUG Test.StreamManage - 
22:38:48.666 [Thread-1] DEBUG Test.StreamManage - E:\intellij_Project\MyScala>echo c =   1>>1.txt 
22:38:48.666 [Thread-1] DEBUG Test.StreamManage - 
22:38:48.666 [Thread-1] DEBUG Test.StreamManage - E:\intellij_Project\MyScala>echo d =   1>>1.txt 
22:38:48.666 [Thread-1] DEBUG Test.StreamManage - 
22:38:48.666 [Thread-1] DEBUG Test.StreamManage - E:\intellij_Project\MyScala>echo e =   1>>1.txt 
22:38:48.666 [Thread-1] DEBUG Test.StreamManage - 
22:38:48.667 [Thread-1] DEBUG Test.StreamManage - E:\intellij_Project\MyScala>shift         
22:38:48.667 [Thread-1] DEBUG Test.StreamManage - 
22:38:48.667 [Thread-1] DEBUG Test.StreamManage - E:\intellij_Project\MyScala>f =   
22:38:48.667 [Thread-1] DEBUG Test.StreamManage - 
22:38:48.667 [Thread-1] DEBUG Test.StreamManage - E:\intellij_Project\MyScala>rem

可以看到这里的打印信息使用了两个线程:Thread-0和Thread-1,分别代表错误输出和标准输出。
我十分郁闷,为什么没有1.txt文件生成。后来仔细想一下,觉得应该是将文件写在了当前的执行程序的目录下,所以在.bat文件所在的目录下没有文件生成。
Java执行cmd命令启动进程_第1张图片
这里的1.txt和a.txt都是生成的目标文件。

4.其它

关于Process,InputStream,InputStreamReader,BufferedReader类详解,可见我的jdk源码解析专栏。

5.参考资料

  • https://www.cnblogs.com/zhufu9426/p/7928570.html

你可能感兴趣的:(Java)