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 中的进程与 锁
理论知识 操作系统背景知识 顾名思义,进程即正在执行的一个过程.进程是对正在运行程序的一个抽象. 进程的概念起源于操作系统,是操作系统最核心的概念,也是操作系统提供的最古老也是最重要的抽象概念之一.操 ...
随机推荐
- Linux修改账户密码
打开终端并登录到要修改密码的账户 输入 passwd 命令,然后 Enter 系统会提示你输入 Current password. 如果是第一次登录或者忘记密码,使用 passwd -d userna ...
- GeminiDB Cassandra接口新特性FLASHBACK发布:任意时间点秒级闪回
本文分享自华为云社区<GeminiDB Cassandra接口新特性FLASHBACK发布:任意时间点秒级闪回>,作者: GaussDB 数据库. 技术背景 数据库作为现代信息系统的核心组 ...
- #倍增FFT#CF755G PolandBall and Many Other Balls
题目 有一排 \(n\) 个球,定义一个组可以只包含一个球或者包含两个相邻的球. 现在一个球只能分到一个组中,求从这些球中取出 \(k\) 组的方案数. \(n\leq 10^9 ,k<2^{1 ...
- 使用OHOS SDK构建googletest
参照OHOS IDE和SDK的安装方法配置好开发环境. 从github下载源码. 执行如下命令: git clone --depth=1 https://github.com/google/googl ...
- JDK10的新特性:var泛型和多个接口实现
目录 简介 实现多个接口 使用多个接口 使用var 总结 简介 在JDK10的新特性:本地变量类型var中我们讲到了为什么使用var和怎么使用var. 今天我们来深入的考虑一下var和泛型,多个接口实 ...
- Python 集合(Sets)3
Python - 合并集合 在 Python 中,有几种方法可以合并两个或多个集合.您可以使用union()方法,该方法返回一个包含两个集合中所有项的新集合,或使用update()方法,将一个集合中的 ...
- 聚焦AI新技术,HMS Core机器学习服务为移动应用智能化注入新动力
近年来,以机器学习为代表的人工智能技术(以下简称AI技术)蓬勃发展.新算法层出不穷,开发出的图像识别.自然语言.活体检测等能力令智能化的未来生活不再遥不可及.同时,这些AI技术正持续演化和发展,数据和 ...
- SilentEye qsnctf wp
题目附件(注:文件名为Luminous.jpg) 根据题目提示,使用SilentEye工具 将图片使用SilentEye打开 使用左下角的Decode解密功能 猜测密码为文件名,输入并开始解密 将被加 ...
- redis 简单整理——redis 的列表基本结构和命令[四]
前言 简单整理一下redis的列表. 正文 列表(list)类型是用来存储多个有序的字符串,如图2-18所示,a. b.c.d.e五个元素从左到右组成了一个有序的列表,列表中的每个字符串 称为元素(e ...
- 重走py 之路 ——列表(一)
前言 因为最近公司有python项目维护,所以把python的基础入门的书整理一遍,因为有些忘记了,同时在看<<python编程>>这本书的时候觉得对有基础的有很多的赘余,打算 ...