Process-与操作系统中的进程进行交互
1、Process介绍
在Java中,Process类是一个抽象类,它提供了与操作系统中的进程进行交互的方法。当你在Java程序中启动一个新的进程(例如,运行一个外部程序或脚本)时,JVM会创建一个Process实例来代表这个新的进程。
Process类提供了以下主要的方法:
- getInputStream():获取进程的标准输出流。你可以从这个流中读取进程的输出。
- getErrorStream():获取进程的错误输出流。你可以从这个流中读取进程的错误输出。
- getOutputStream():获取进程的标准输入流。你可以向这个流中写入数据,作为进程的输入。
- waitFor():等待进程结束,并返回进程的退出状态码。
- exitValue():获取进程的退出状态码。如果进程还没有结束,这个方法会抛出IllegalThreadStateException。
- destroy():强制结束进程。
以下是一个使用Process类的例子,它启动一个新的进程来运行ping命令:
Process process = Runtime.getRuntime().exec("ping www.google.com");
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
process.waitFor();
在这个例子中,我们首先使用Runtime.exec方法启动一个新的进程来运行ping命令。然后,我们创建一个BufferedReader来读取进程的输出。最后,我们使用Process.waitFor方法等待进程结束。
2、使用
- 使用Runtime.getRuntime().exec("java -c"),相当于调用三方库(三方程序)
- Runtime.getRuntime().exec()
Runtime.getRuntime().exec(参数1)
参数1是:执行的命令
Runtime.getRuntime().exec(参数1,参数2,参数3)
参数1是:执行的命令
参数3是:程序执行的文件夹,如:/phantomjs211/linux/bin
3、获取执行进程的pid(jdk8)
3.0、Java 9及更高版本,可以直接获取。
Process process = Runtime.getRuntime().exec("some-command");
long pid = process.pid();
System.out.println("PID: " + pid);
3.1、JNA、JNA和Process
- Java Native Access (JNA)库
Java Native Access (JNA) 是一个开源的Java库,它允许Java程序调用C和C++编写的本地应用程序接口(API)和库,而无需使用Java Native Interface (JNI) 或编写任何本地代码。
在传统的JNI使用中,Java开发者需要编写本地方法的Java声明,然后使用特定的工具生成C或C++的头文件,接着在这些头文件中实现本地方法。这个过程相当复杂,需要对C或C++有一定的了解,而且还需要处理本地代码的编译和分发。
相比之下,JNA大大简化了这个过程。使用JNA,你只需要在Java代码中声明本地方法的接口,然后JNA会自动处理与本地代码的交互,包括参数的转换和内存的管理。这意味着你可以直接在Java代码中调用本地方法,而无需编写或理解任何C或C++代码。
例如,假设你有一个C库,它提供了一个名为doSomething的函数。在JNI中,你需要编写C代码来实现一个与doSomething对应的本地方法。但在JNA中,你只需要声明一个接口,如下所示:
- JNA和Process的关系、区别
Process类和Java Native Access (JNA)库都是Java中与本地系统交互的方式,但它们的用途和工作方式有所不同。
Process类是Java标准库的一部分,它用于创建和控制操作系统的进程。你可以使用Process类来执行外部命令,然后获取命令的输出或错误信息,或者控制命令的输入。Process类提供了一种简单的方式来与操作系统的shell交互,但它的功能相对有限,主要限于启动新的进程和与这些进程进行简单的交互。
Java Native Access (JNA)库则提供了一种更直接和强大的方式来与本地系统交互。使用JNA,你可以直接调用操作系统的API,或者使用其他本地库。这意味着你可以在Java代码中使用本地系统的所有功能,而不仅仅是启动新的进程。然而,使用JNA通常需要对本地系统的API有一定的了解,而且JNA的使用也比Process类更复杂。
总的来说,Process类和JNA库都是Java中与本地系统交互的工具,但它们的功能和使用场景有所不同。
Process类主要用于启动和控制新的进程,而JNA库则提供了一种更直接和强大的方式来使用本地系统的API和库。
3.2、导包(gradle)
// implementation 'net.java.dev.jna:jna:5.12.1'
implementation 'net.java.dev.jna:jna-platform:5.12.1'
3.3、工具类-测试
package com.cc.urlgethtml.utils;
import com.sun.jna.Platform;
import com.sun.jna.Pointer;
import com.sun.jna.platform.win32.Kernel32;
import com.sun.jna.platform.win32.WinNT;
import java.io.BufferedReader;
import java.io.File;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.reflect.Field;
import java.util.Objects;
import java.util.Optional;
/**
* <p>JnaPlatform:获取执行命令的pid</p>
*
* @author CC
* @since 2023/11/6
*/
public class JnaPlatform {
public static void main(String[] args) {
Process process = null;
try {
//执行命令
if (Platform.isWindows()) {
process = Runtime.getRuntime().exec("java -version", new String[]{},
new File("D:\\"));
}else {
process = Runtime.getRuntime().exec("ls -l");
}
//获取日志
InputStream inputStream = process.getErrorStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
String msg;
while ((msg = reader.readLine()) != null) {
System.out.println(msg);
}
//获取pid
Optional<Integer> pid = getPid(process);
System.out.println("pid----" + pid.orElse(-1));
}catch(Exception e){
throw new RuntimeException(e.getMessage());
}finally {
if (Objects.nonNull(process)) {
process.destroy();
}
}
}
/** <p>获取pid<p>
* @param process process
* @return {@link Optional<Integer>}
* @since 2023/11/6
* @author CC
**/
public static Optional<Integer> getPid(Process process) {
if (Platform.isLinux()) {
/* Linux platform */
try {
Field pidField = process.getClass().getDeclaredField("pid");
pidField.setAccessible(true);
return Optional.of((Integer) pidField.get(process));
} catch (NoSuchFieldException | IllegalAccessException e) {
return Optional.empty();
}
} else if (Platform.isWindows()) {
/* Windows platform */
try {
Field handleField = process.getClass().getDeclaredField("handle");
handleField.setAccessible(true);
long handl = (Long) handleField.get(process);
Kernel32 kernel = Kernel32.INSTANCE;
WinNT.HANDLE hand = new WinNT.HANDLE();
hand.setPointer(Pointer.createConstant(handl));
int pid = kernel.GetProcessId(hand);
return Optional.of(pid);
} catch (NoSuchFieldException | IllegalAccessException e) {
return Optional.empty();
}
}
return Optional.empty();
}
/** <p>根据pid停止进程-待实现<p>
* @since 2023/11/6
* @author CC
**/
public boolean kill(String pId){
return true;
}
}
- 结果

Process-与操作系统中的进程进行交互的更多相关文章
- c#Winform程序调用app.config文件配置数据库连接字符串 SQL Server文章目录 浅谈SQL Server中统计对于查询的影响 有关索引的DMV SQL Server中的执行引擎入门 【译】表变量和临时表的比较 对于表列数据类型选择的一点思考 SQL Server复制入门(一)----复制简介 操作系统中的进程与线程
c#Winform程序调用app.config文件配置数据库连接字符串 你新建winform项目的时候,会有一个app.config的配置文件,写在里面的<connectionStrings n ...
- 5、CPU 的线程与操作系统的线程有何关系?操作系统中的进程和线程是什么关系?
CPU中的线程和操作系统(OS)中的线程即不同,在调度的时候又有些关联.CPU中的线程,我们叫它们Thread,和OS中的线程的名字一样.它来自同步多线程(SMT,Simultaneous Multi ...
- 第二十一篇:Linux 操作系统中的进程结构
前言 在 Linux 中,一个正在执行的程序往往由各种各样的进程组成,这些进程除了父子关系,还有其他的关系.依赖于这些关系,所有进程构成一个整体,给用户提供完整的服务( 考虑到了终端,即与用户的交互 ...
- Linux 操作系统中的进程结构
前言 在 Linux 中,一个正在执行的程序往往由各种各样的进程组成,这些进程除了父子关系,还有其他的关系.依赖于这些关系,所有进程构成一个整体,给用户提供完整的服务( 考虑到了终端,即与用户的交互 ...
- 在Python程序中的进程操作,multiprocess.Process模块
在python程序中的进程操作 之前我们已经了解了很多进程相关的理论知识,了解进程是什么应该不再困难了,刚刚我们已经了解了,运行中的程序就是一个进程.所有的进程都是通过它的父进程来创建的.因此,运行起 ...
- python 全栈开发,Day38(在python程序中的进程操作,multiprocess.Process模块)
昨日内容回顾 操作系统纸带打孔计算机批处理 —— 磁带 联机 脱机多道操作系统 —— 极大的提高了CPU的利用率 在计算机中 可以有超过一个进程 进程遇到IO的时候 切换给另外的进程使用CPU 数据隔 ...
- Python程序中的进程操作-开启多进程(multiprocess.process)
目录 一.multiprocess模块 二.multiprocess.process模块 三.process模块介绍 3.1 方法介绍 3.2 属性介绍 3.3 在windows中使用process模 ...
- 29、Python程序中的进程操作(multiprocess.process)
一.multiprocess模块 multiprocess不是一个模块而是python中一个操作.管理进程的包. 子模块分为四个部分: 创建进程部分 进程同步部分 进程池部分 进程之间数据共享 二.m ...
- 在python程序中的进程操作
multiprocess模块 multiprocess不是一个模块而是python中一个操作.管理进程的包. 之所以叫multi是取自multiple的多功能的意思,在这个包中几乎包含了和进程有关的所 ...
- Python 中的进程与 锁
理论知识 操作系统背景知识 顾名思义,进程即正在执行的一个过程.进程是对正在运行程序的一个抽象. 进程的概念起源于操作系统,是操作系统最核心的概念,也是操作系统提供的最古老也是最重要的抽象概念之一.操 ...
随机推荐
- 在 .NET 中使用 OPC UA 协议
目录 什么是 OPC UA UaExpert 的使用 下载 UaExpert 首次启动 添加 OPC UA 服务器 连接 OPC UA 服务器 查看 PLC 数据 使用 C# 读写 OPC UA 数据 ...
- SpringBoot 常用注解总结
核心注解 1. @SpringBootApplication 主要用于开启自动配置,它也是一个组合注解,主要组合了 @SpringBootConfiguration.@EnableAutoConfig ...
- TCL之基本语法1
TCL之基本语法1 1:set and puts set就是变量声明,这个声明在需要使用的指令下会自动执行,不会出现没有声明的错误.但是对于puts这类定向访问的是不能没有声明的.这里简单理解TCL ...
- [ROS串口通信]Serial库读入结构体
本文介绍使用c++中Serial库读入结构体: //例如,结构体定义如下: typedef struct __attribute__((packed)) { uint16_t team; /* 本身队 ...
- KingbaseESV8R6识别IO使用率过高
前言 数据库正常运行离不开I/O的使用,在操作系统上,I/O又离不开存储的性能及使用方式,我们可以在存储层利用raid条带化技术使IOPS达到最佳性能. 本篇文章有助于确认数据库I/O使用率过高的原因 ...
- archlinux 格式化分区并创建文件系统后,分区的文件系统没有改变
这就需要格式化分区并创建文件系统后 再执行partprobe应该就可以看到分区的文件系统改变了 partprobe partprobe命令用于通知操作系统重新读取分区表,以便识别新创建的分区或者删除的 ...
- 给你的wordpress添加文章内图片鼠标点击放大浏览的功能吧~
注:笔者已启用WP Githuber MD插件使用Markdown语法进行文章编辑,启用的主题为generatepress. 1.进入你的宝塔面板首页 点击文件选项: 2.分别找到以下几个文件进行修改 ...
- Scala编译原理
1 package com.atguigu.chapter01; 2 /** 3 * 4 */ 5 //main 方法名 6 //小括号表示参数列表 7 // 参数声明方式: java -> 类 ...
- C#添加自定义控件
1.vs 控件工具箱添加选项卡 2.输入选项卡名称 我这里是Emgucv 3.点击选择项 4.点击浏览 找到Emgu.CV.Platform.NetFramework.dll 这是emgucv的C#控 ...
- van-cell如何使用插槽
van-cell 是 Vant 组件库中的一个单元格组件,用于展示列表中的信息.Vant 是一个轻量.可靠的移动端 Vue 组件库. 在 Vant 中,van-cell 组件提供了多个插槽(slot) ...