利用java执行dos命令(使用时出现的各种问题总结)


public class Runtime
extends Object
Every Java application has a single instance of class Runtime that allows the application to interface with the environment in which the application is running. The current runtime can be obtained from the getRuntime method.
An application cannot create its own instance of this class.
public static Runtime getRuntime()
Returns the runtime object associated with the current Java application. Most of the methods of class Runtime are instance methods and must be invoked with respect to the current runtime object.

单例

public class runtime {
    public static void main(String[] args) {
        Runtime run1 = Runtime.getRuntime();
        Runtime run2 = Runtime.getRuntime();
        Runtime run3 = Runtime.getRuntime();
        System.out.println(run1);
        System.out.println(run2);
        System.out.println(run3);
    }
}

out:
java.lang.Runtime@677327b6
java.lang.Runtime@677327b6
java.lang.Runtime@677327b6

Process finished with exit code 0

单条指令测试

Runtime run = Runtime.getRuntime();
Process dos = run.exec("cmd /c start(空格一个)" + "jps");//dos窗口闪退
Process dos = run.exec("cmd /k start(空格一个)" + "jps");//dos窗口闪退
Process dos = run.exec("cmd /k start " + "dir");//dos窗口出现,没有退出

bat文件测试

public static void main(String[] args) throws IOException, InterruptedException {
        Runtime run = Runtime.getRuntime();

        File fpath = new File("cmd.bat");
        System.out.println(fpath.getAbsoluteFile());// 绝对路径 C:\workspace\java\zby_JavaReference\cmd.bat
        Process dos = run.exec("cmd /c" + fpath.getAbsoluteFile());//start后面一定要加空格(当start后面有别的命令时)
        
        BufferedReader in = new BufferedReader(new InputStreamReader(dos.getInputStream(), "GBK"));
        
        String line = null;
        while((line = in.readLine()) != null){
            System.out.println(line);
        }
        in.close();
    }
"cmd.bat"
----------------------------
java -version
jps
空行(测试空行是否影响运行)
dir
groovy -version
dir
java -version
jps
----------------------------

idea输出窗口:
C:\workspace\java\zby_JavaReference\cmd.bat

C:\workspace\java\zby_JavaReference>java -version //没有输出(原因不明)

C:\workspace\java\zby_JavaReference>jps
12472 testcmd
13464 Jps
4680 
7260 KotlinCompileDaemon
9884 Launcher

C:\workspace\java\zby_JavaReference>dir
 驱动器 C 中的卷是 OS
 卷的序列号是 CE2B-C0E5

 C:\workspace\java\zby_JavaReference 的目录

2019/12/10  19:58    <DIR>          .
2019/12/10  19:58    <DIR>          ..
2019/12/10  19:55    <DIR>          .idea
2019/11/21  09:42                18 a.txt
2019/12/09  17:09    <DIR>          algorithm
2019/09/26  22:05               822 b.txt
2019/09/26  19:37               150 c.txt
2019/12/10  19:58                65 cmd.bat
2019/12/09  16:18    <DIR>          Demo_1.0
2019/10/13  16:01    <DIR>          DesignMode
2019/12/09  16:34    <DIR>          DesignPattern
2019/09/26  18:38                 0 e.txt
2019/11/21  10:37                20 f.txt
2019/12/09  16:18    <DIR>          groovyTest
2019/09/26  15:44    <DIR>          JDK
2019/12/09  16:20    <DIR>          JVM
2019/12/09  18:03    <DIR>          other
2019/09/25  22:02    <DIR>          out
               6 个文件          1,075 字节
              12 个目录 30,710,775,808 可用字节

C:\workspace\java\zby_JavaReference>groovy -version 
Groovy Version: 2.5.8 JVM: 1.8.0_221 Vendor: Oracle Corporation OS: Windows 10
//停了(原因不明)
Process finished with exit code 0

具体使用示例1

感觉还是用bat文件比较好处理
下面是使用bat文件的一个抛砖引玉类:
循环运行查看记事本软件是否打开(巨耗cpu和内存)

"cmd.bat"文件
---------------------------------------
TASKLIST /FI "IMAGENAME eq notepad.exe"
---------------------------------------

import java.io.*;

public class exec_cmd {
    public static void main(String[] args) throws IOException, InterruptedException {
        //
        Runtime run = Runtime.getRuntime();
        //文件路径
        File fpath = new File("cmd.bat");
        String batpath = fpath.getAbsolutePath();
        //建立对象
        exec_cmd t = new exec_cmd();
        //开线程,该线程循环查找系统中是否有notepad.exe正在运行
        new Thread(() -> {
            while(true)
            System.out.println(t.execbat(batpath, run));
        }).start();
        
        //主线程休眠3秒后打开记事本
        Thread.sleep(1000*3);
        Process notepad = run.exec("notepad");
    }

    public StringBuilder execbat(String batpath,Runtime run){
        // 标准输出
        InputStream standardInput = null;
        BufferedReader standardReader = null;
        // 错误输出
        InputStream errInput = null;
        BufferedReader errReader = null;
        //dos输出保存
        StringBuilder standardMsg = new StringBuilder();
        StringBuilder errMsg = new StringBuilder();
        //
        Process dos = null;
        try {
            //运行命令
            dos = run.exec(batpath);
            //dos运行结果获取
            standardInput = dos.getInputStream();
            standardReader = new BufferedReader(new InputStreamReader(standardInput, "GBK"));
            String line = null;
            while ((line = standardReader.readLine()) != null) {
                standardMsg.append(line).append("\n");
            }
            //dos运行错误信息获取
            errInput = dos.getErrorStream();
            if(errInput != null){
                errReader = new BufferedReader(new InputStreamReader(errInput,"GBK"));
            }
            if(errMsg.length() > 0){
                throw new DosExecException(standardMsg.append(errMsg).toString());
            }
        } catch (IOException e) {
            e.printStackTrace();
            throw new DosExecException(standardMsg.append(errMsg).toString());
        } finally {
            // 销毁进程对象
            if (dos != null) {
                dos.destroy();
            }
            //关闭流
            if (null != standardReader) {
                try {
                    standardReader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (null != errReader) {
                try {
                    errReader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return standardMsg;
    }
}

out:
C:\workspace\java\zby_JavaReference>TASKLIST /FI "IMAGENAME eq notepad.exe" 
信息: 没有运行的任务匹配指定标准。
.
.
.
C:\workspace\java\zby_JavaReference>TASKLIST /FI "IMAGENAME eq notepad.exe" 
信息: 没有运行的任务匹配指定标准。
(3秒,记事本开启)
C:\workspace\java\zby_JavaReference>TASKLIST /FI "IMAGENAME eq notepad.exe" 

映像名称                       PID 会话名              会话#       内存使用 
========================= ======== ================ =========== ============
notepad.exe                   4416 Console                    1     10,132 K


C:\workspace\java\zby_JavaReference>TASKLIST /FI "IMAGENAME eq notepad.exe" 

映像名称                       PID 会话名              会话#       内存使用 
========================= ======== ================ =========== ============
notepad.exe                   4416 Console                    1     24,624 K
.
.
.
.

具体使用示例2

改:将方法中的两个对象拿出来,避免重复new对象

StringBuilder standardMsg = new StringBuilder();
StringBuilder errMsg = new StringBuilder();

加入字符判断语句,用来跳出循环,关闭线程。

if(t.standardMsg.indexOf("没有运行") == -1)
import java.io.*;

public class exec_cmd {
    //改动的位置
    StringBuilder standardMsg = new StringBuilder();
    StringBuilder errMsg = new StringBuilder();

    public static void main(String[] args) throws IOException, InterruptedException {
        Runtime run = Runtime.getRuntime();
        File fpath = new File("cmd.bat");
        String batpath = fpath.getAbsolutePath();
        exec_cmd t = new exec_cmd();
 
        Thread find = new Thread(() -> {
            while(true) {
                t.execbat(batpath, run);
                System.out.println(t.standardMsg);
                //改动的位置
                if(t.standardMsg.indexOf("没有运行") == -1){
                    break;
                }
                //清除这次运行得到的输出字符串
                t.standardMsg.delete(0,t.standardMsg.length());
            }
        });
        find.start();

        Thread.sleep(1000*20);
        Process notepad = run.exec("notepad");
        System.out.println("记事本打开");
        System.out.println(t.standardMsg);
        //System.out.println(t.execbat(batpath, run));


    }

    public void execbat(String batpath,Runtime run){
        // 标准输出
        InputStream standardInput = null;
        BufferedReader standardReader = null;
        // 错误输出
        InputStream errInput = null;
        BufferedReader errReader = null;

        Process dos = null;
        try {
            dos = run.exec(batpath);
            standardInput = dos.getInputStream();
            standardReader = new BufferedReader(new InputStreamReader(standardInput, "GBK"));
            String line = null;
            while ((line = standardReader.readLine()) != null) {
                standardMsg.append(line).append("\n");
            }
            errInput = dos.getErrorStream();
            if(errInput != null){
                errReader = new BufferedReader(new InputStreamReader(errInput,"GBK"));
            }
            if(errMsg.length() > 0){
                throw new DosExecException(standardMsg.append(errMsg).toString());
            }
        } catch (IOException e) {
            e.printStackTrace();
            throw new DosExecException(standardMsg.append(errMsg).toString());
        }finally {
            // 销毁进程对象
            if (dos != null) {
                dos.destroy();
            }
            if (null != standardReader) {
                try {
                    standardReader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (null != errReader) {
                try {
                    errReader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

文件路径C:/dos2/
路径下有文件
c.bat
command.txt:dir(内容)

dat文件
@ECHO OFF
SETLOCAL EnableDelayedExpansion
FOR /F %%A IN (command.txt) DO (
SET NextC=%%A
!NextC!>>log.txt
)
ENDLOCAL
----------------------------------------------------------------
1.直接双击c.bat文件可运行,在c.bat文件所在目录中生成log.txt文件
2.利用Runtime.getRuntime().exec()去运行,报错:系统找不到文件 command.txt。
--------------------------------------------------------------------
dat文件
@ECHO OFF
SETLOCAL EnableDelayedExpansion
FOR /F %%A IN (C:/dos2/command.txt) DO (
SET NextC=%%A
!NextC!>>log.txt
)
ENDLOCAL
---------------------------------------------------------
不报错,对于idea,在idea的工程根目录内生成log.txt文件
猜测与RunTime()有关,待查---->原因------>启动的dos 默认路径是你工程的根目录
---------------------------------------------------------
@ECHO OFF
SETLOCAL EnableDelayedExpansion
FOR /F %%A IN (C:/dos2/command.txt) DO (
SET NextC=%%A
!NextC!>>C:/dos2/log.txt
)
ENDLOCAL
---------------------------------------------------------
正确运行与生成
---------------------------------------------------------

log.txt
 驱动器 C 中的卷是 OS
 卷的序列号是 CE2B-C0E5

 C:\workspace\java\zby_JavaReference 的目录  //启动的dos 默认路径是你工程的根目录

2019/12/16  14:26    <DIR>          .
2019/12/16  14:26    <DIR>          ..
2019/12/16  14:31    <DIR>          .idea
2019/11/21  09:42                18 a.txt
2019/12/09  17:09    <DIR>          algorithm
2019/09/26  22:05               822 b.txt
2019/09/26  19:37               150 c.txt
2019/12/11  11:15                41 cmd.bat
2019/12/09  16:18    <DIR>          Demo_1.0
2019/10/13  16:01    <DIR>          DesignMode
2019/12/09  16:34    <DIR>          DesignPattern
2019/09/26  18:38                 0 e.txt
2019/11/21  10:37                20 f.txt
2019/12/09  16:18    <DIR>          groovyTest
2019/09/26  15:44    <DIR>          JDK
2019/12/09  16:20    <DIR>          JVM
2019/12/16  14:31             2,048 log.txt
2019/12/16  13:50    <DIR>          other
2019/09/25  22:02    <DIR>          out
               7 个文件          3,099 字节
              12 个目录 56,327,733,248 可用字节
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值