首页 > 编程语言 >Java执行操作系统命令-Process抽象类(1)

Java执行操作系统命令-Process抽象类(1)

时间:2022-12-19 20:23:12浏览次数:68  
标签:Java String Process cmd cs ben 抽象类 dir

Java 8

Windows 10

Eclipse Version: 2022-09 (4.25.0)

--

 

序章

测试使用Java程序执行操作系统命令。ben发布于博客园

需要用到 抽象类Process:

// @since   JDK1.0
public abstract class Process {
//...
}

 在类注释中,提到了 ProcessBuilder、Runtime 两个类,用来生成Process对象——执行命令。ben发布于博客园

注,本文仅涉及Windows上的命令执行。

注,本文只测试执行Windows命令 cd、dir 两个命令。ben发布于博客园

 

测试目录:D:\javaprocess

 

涉及类:

java.lang.Process
java.lang.ProcessBuilder
java.lang.Runtime

 

执行命令:使用ProcessBuilder类

ProcessBuilder类 结构:ben发布于博客园

 

测试代码:输出执行后的 InputStream、ErrorStream 的内容。

	/**
	 * 测试:ProcessBuilder
	 */
	public static void test1(String... cmd) {
		cs.accept("start test1..");
		try {
			Process ps = new ProcessBuilder()
					.command(cmd)
					.start();
			
			cs.accept("1、InputStream:");
			processIs(ps.getInputStream());
			cs.accept("2、ErrorStream:");
			processIs(ps.getErrorStream());
			cs.accept("3、----END----");
		} catch (IOException e) {
			e.printStackTrace();
		}	
	}

	/**
	 * 输出InputStream的内容:字符集 GB2312
	 * @param is
	 * @throws IOException
	 */
	private static void processIs(InputStream is) throws IOException {
		final int size = 1024;
		byte[] buffer = new byte[size];

		Charset cset = Charset.forName("GB2312");
		cs.accept("cset=" + cset);
		
		StringBuffer sb = new StringBuffer();
		
		int ret = 0;
		int total = 0;
		while ((ret = is.read(buffer, 0, size)) > 0) {
			total += ret;
			String chunk = new String(buffer, 0, ret, cset);
			
			sb.append(chunk);
		}

		cs.accept("ret=" + ret + ", total=" + total);
		cs.accept("sb=" + sb.length() + ", content=" + sb);
		
		is.close();
	}

 

测试存在的目录

执行:test1("cmd", "/C", "dir", "d:\\javaprocess");ben发布于博客园

注意,这里的 cmd、/C 是必须的(Windows中)。

测试结果:目录存在,正常输出。

目录存在,执行正常,InputStream有数据,而ErrorStream没有数据。ben发布于博客园

 

测试不存在的目录

执行:test1("cmd", "/C", "dir", "d:\\javaprocessnull");ben发布于博客园

测试结果:目录不存,ErrorInput也要数据输出——找不到文件。

 

问题:这里的 InputStream 也有数据,是否可以将两者合并呢?ben发布于博客园

回答:可以。在start()之前执行 redirectErrorStream(true) 即可。

 

问题:测试时传入了4个参数,可以合并为一个吗?ben发布于博客园

回答:不可以。

执行 test1("cmd /C dir d:\\javaprocess");

测试结果:CreateProcess error=2, 系统找不到指定的文件。ben发布于博客园

 

执行命令:使用Runtime类

Runtime类 结构:

执行命令会用到其中的 exec函数,可以看到 exec函数有多个函数签名。

// 字符串的命令
public Process exec(String command) throws IOException {}
public Process exec(String command, String[] envp) throws IOException {}
public Process exec(String command, String[] envp, File dir) throws IOException {}

// 字符数组的命令
public Process exec(String cmdarray[]) throws IOException {}
public Process exec(String[] cmdarray, String[] envp) throws IOException {}
public Process exec(String[] cmdarray, String[] envp, File dir) throws IOException {}

 

测试代码:test2(String cmd)

	/**
	 * 测试:Runtime.getRuntime().exec(...)
	 */
	public static void test2(String cmd) {
		cs.accept("start test2..cmd=" + cmd);
		try {
			Process ps = Runtime.getRuntime().exec(cmd);

			cs.accept("1、InputStream:");
			processIs(ps.getInputStream());
			cs.accept("2、ErrorStream:");
			processIs(ps.getErrorStream());
			cs.accept("3、----END----");
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

注,会使用前面的 processIs(InputStream is) 函数。

 

测试存在的目录

执行:test2("cmd /C dir d:\\javaprocess");

测试结果:

注意,这里的命令是一个字符串。

 

测试不存在的目录

执行:test2("cmd /C dir d:\\javaprocessnull");

测试结果:

  问题:这里的ErrorStream也有数据了,可以重定向到InputSteam吗? 回答:TODO  

多条命令执行:Runtime类

场景:进入一个目录,再输出目录下的内容。

执行下面的语句可以实现吗?

test2("cmd /C cd d:\\javaprocess");
test2("cmd /C dir .");

回答:不可以。

两个Process是不同的进程——即不同的JVM。

 

执行多条命令,在使用Runtime类时,可以使用 && 符号。

执行:test2("cmd /C cd d:\\javaprocess && dir"); 或者 test2("cmd /C cd d:\\javaprocess && dir .");

测试结果:

 

问题:ProcessBuilder类 怎么执行多条命令呢?TODO

 

 

 

参考资料

1、java Process 执行批命令 cmd
by 老谭TYH
于 2022-11-22 12:18:50 发布
原文链接:https://blog.csdn.net/qq_30436011/article/details/127979994

2、

 

ben发布于博客园

 

标签:Java,String,Process,cmd,cs,ben,抽象类,dir
From: https://www.cnblogs.com/luo630/p/16992772.html

相关文章

  • Java关键词final解读
    目录1final基本用法1.1final修饰变量1.2final修饰方法参数1.3final修饰方法1.4final修饰类1.5空白final1.6staticfinal2jvm角度理解final不可变性3final多线程下......
  • Java笔记(7)——equals和toString方法的重写和一个例子
    1.Object类​​Object​​​类是所有类的根父类,如果在类中没有​​extends​​关键字指明其父类,默认其父类为Object类。2.==与equals方法的区别​​==​​​:是否指向了同......
  • Java笔记(8)——重载(Overload)与重写(Override)的区别
    1、重写(Override)  重写是子类对允许访问的父类的方法进行重新编写的过程,方法名、返回值和参数列表不能变,方法中的内容可以变化。特点就是:子类可以根据自己的需要对父类的......
  • Java笔记(10)——异常处理
    1、Java异常  Java运行时发生异常可以分为两类:​​Error​​​:​​JVM​​系统内部错误、资源耗尽等问题产生的异常。​​Exception​​:编程错误或偶然的外在因素导致的......
  • Java笔记(5)——类的继承、访问控制、super关键字
      在类中,不写构造方法,相当于执行了默认的无参构造方法;写了有参构造方法,则只执行有参构造方法,默认的无参构造方法则会被屏蔽掉;若想拥有有参和无参构造方法,则同时显示地写出......
  • JAVA方法
    JAVA方法定义方法的本意是功能块,就是实现某个功能的语句块的集合。我们设计方法的时候最好保持方法的原子性,就是一个方法只完成一个功能,这样利于我们后期扩展。JAVA的......
  • 【校招VIP】线上实习 推推 书籍详情模块 Java开发文档周最佳
    【推推】主要是为校招设计的小说一更新就通知的项目,每个模块都具有亮点和难点,项目表现为手机网站应用,可嵌入小程序或APP中。恭喜来自四川师范大学的o0hana同学获得本......
  • process 进程监控
    常见的进程监控配置查看监控状态process_exporter.serviceroot@ph-drt-v-66-232-live:~#systemctlstatusprocess_exporter.service●process_exporter.service-......
  • java8特性-list集合根据多个字段去重
    //按专业和年级去重,专业和年纪一样时表示重复对象List<Class>distinctClass=classList.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(()-......
  • 通过javacv对视频每隔1秒钟截取1张图片
     Exceptioninthread"main"java.lang.NoClassDefFoundError:Couldnotinitializeclassorg.bytedeco.javacpp.avutilatjava.lang.Class.forName0(NativeMethod)at......