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 中的进程与 锁
理论知识 操作系统背景知识 顾名思义,进程即正在执行的一个过程.进程是对正在运行程序的一个抽象. 进程的概念起源于操作系统,是操作系统最核心的概念,也是操作系统提供的最古老也是最重要的抽象概念之一.操 ...
随机推荐
- 马文·柯林斯的教育之道 「Marva Collins' Way」 阅读笔记
<马文·柯林斯的教育之道> 是 哈佛幸福课(积极心理学) 中强列推荐的一本书 这本书主写的是 马文·柯林斯 的成长经历已经和教育理念,仅看介绍,会误认为这本书只是在说鼓励式的教学理念,看完 ...
- EVENG导入Win7镜像以后可以启动无法VNC打开
原因:未安装支持 eveng 的 vncviewer 解决方法:下载 vncviewer: https://pan.eve-ng.cn/Tools/EVE-NG/Client/EVE-NG-Win-C ...
- Python - inspect 模块的简单使用
Python中的inspect模块解析 Python的inspect模块是一个强大的内省工具,允许开发者检查(inspect)活动对象和源代码.它提供了一系列函数,用于获取信息关于正在运行的程序和调用 ...
- KingbaseES V8R6 几种不同的表复制方式
前言 当数据库遇到未知问题,有时候无法入手分析,在非生产数据库或者征得客户同意获得特殊时间,需要重建表解决,下面提供了多种不同的复制表的方法,我们了解一下他们的差异. 测试 1.CREATE TABL ...
- Amazon免费CE2基于docker部署nginx,并实现访问
在部署之前,请确保你已经申请好了CE2免费的服务器,网上的相关教程很多,可以自由参考. 一.使用xshell+公钥连接实例 1.打开xshell,导入密钥, 选择"工具" -> ...
- jenkens2权威指南
第1章 Jenkins简介 Jenkins 2是什么 JobConfigHistory:这个插件可以追溯XML配置的历史版本信息, 并且允许你查看每次变更的内容. JenkinsFile Jenkin ...
- Mysql Order 排序的时候占用很长时间解决思路
MySQL中的连表查询(JOIN)在进行ORDER BY排序时可能会变得很慢,尤其是当处理大量数据时.以下是一些优化策略,可以帮助减少排序操作的时间: 索引优化: 确保参与排序的列上有索引.如果排序的 ...
- C# 布尔值和条件语句:入门指南和实用示例
C# 布尔值 在编程中,通常需要一个只能有两个值之一的数据类型,比如: 是 / 否 开 / 关 真 / 假 为此,C# 有一个 bool 数据类型,可以取 true 或 false 的值. 布尔值 使 ...
- VS 2020制作安装包
VS制作安装包的一般步骤. 一·新建项目 (1)新建 (2)界面跳转 二·添加引用 (1)添加卸载程序 1.在'C:WINDOWSsystem32'路径下,找到msiexec.exe . 2.将msi ...
- Makefile编写模板 & 学习笔记
一.模板 # 伪命令 .PHONY: clean compileSo compileExe run: compileExe @./main compileExe: compileSo @g++ mai ...