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-与操作系统中的进程进行交互的更多相关文章

  1. c#Winform程序调用app.config文件配置数据库连接字符串 SQL Server文章目录 浅谈SQL Server中统计对于查询的影响 有关索引的DMV SQL Server中的执行引擎入门 【译】表变量和临时表的比较 对于表列数据类型选择的一点思考 SQL Server复制入门(一)----复制简介 操作系统中的进程与线程

    c#Winform程序调用app.config文件配置数据库连接字符串 你新建winform项目的时候,会有一个app.config的配置文件,写在里面的<connectionStrings n ...

  2. 5、CPU 的线程与操作系统的线程有何关系?操作系统中的进程和线程是什么关系?

    CPU中的线程和操作系统(OS)中的线程即不同,在调度的时候又有些关联.CPU中的线程,我们叫它们Thread,和OS中的线程的名字一样.它来自同步多线程(SMT,Simultaneous Multi ...

  3. 第二十一篇:Linux 操作系统中的进程结构

    前言 在 Linux 中,一个正在执行的程序往往由各种各样的进程组成,这些进程除了父子关系,还有其他的关系.依赖于这些关系,所有进程构成一个整体,给用户提供完整的服务( 考虑到了终端,即与用户的交互 ...

  4. Linux 操作系统中的进程结构

    前言 在 Linux 中,一个正在执行的程序往往由各种各样的进程组成,这些进程除了父子关系,还有其他的关系.依赖于这些关系,所有进程构成一个整体,给用户提供完整的服务( 考虑到了终端,即与用户的交互 ...

  5. 在Python程序中的进程操作,multiprocess.Process模块

    在python程序中的进程操作 之前我们已经了解了很多进程相关的理论知识,了解进程是什么应该不再困难了,刚刚我们已经了解了,运行中的程序就是一个进程.所有的进程都是通过它的父进程来创建的.因此,运行起 ...

  6. python 全栈开发,Day38(在python程序中的进程操作,multiprocess.Process模块)

    昨日内容回顾 操作系统纸带打孔计算机批处理 —— 磁带 联机 脱机多道操作系统 —— 极大的提高了CPU的利用率 在计算机中 可以有超过一个进程 进程遇到IO的时候 切换给另外的进程使用CPU 数据隔 ...

  7. Python程序中的进程操作-开启多进程(multiprocess.process)

    目录 一.multiprocess模块 二.multiprocess.process模块 三.process模块介绍 3.1 方法介绍 3.2 属性介绍 3.3 在windows中使用process模 ...

  8. 29、Python程序中的进程操作(multiprocess.process)

    一.multiprocess模块 multiprocess不是一个模块而是python中一个操作.管理进程的包. 子模块分为四个部分: 创建进程部分 进程同步部分 进程池部分 进程之间数据共享 二.m ...

  9. 在python程序中的进程操作

    multiprocess模块 multiprocess不是一个模块而是python中一个操作.管理进程的包. 之所以叫multi是取自multiple的多功能的意思,在这个包中几乎包含了和进程有关的所 ...

  10. Python 中的进程与 锁

    理论知识 操作系统背景知识 顾名思义,进程即正在执行的一个过程.进程是对正在运行程序的一个抽象. 进程的概念起源于操作系统,是操作系统最核心的概念,也是操作系统提供的最古老也是最重要的抽象概念之一.操 ...

随机推荐

  1. C# OpenCv DNN 人脸检测

    using OpenCvSharp; using OpenCvSharp.Dnn; using System; using System.Collections.Generic; using Syst ...

  2. 京东二面:Redis为什么快?我说Redis是纯内存访问的,然后他对我笑了笑。。。。。。

    引言 Redis是一个高性能的开源内存数据库,以其快速的读写速度和丰富的数据结构支持而闻名.作为一个轻量级.灵活的键值存储系统,Redis在各种应用场景下都展现出了惊人的性能优势.无论是作为缓存工具. ...

  3. KingabseES 构造常量数据表的方式 union, values, array

    背景 通用报表系统中,如果过滤条件是多选数据项,需要动态构造虚拟数据表,这里也会成为查询性能的痛点. 构造方式与执行计划 构造1000行数据的虚拟表. SQL UNION 组合多个查询的结果,需要解析 ...

  4. Sealos 开源初创公司 Trending 全球 TOP50,中国第二!

    今年,Runa Capital (鲁纳资本) 评选出了 2023 年增长最快的 50 家开源创业公司,Sealos 压轴登场,总共有两家中国公司上榜,Sealos 排名第二. Runa Capital ...

  5. 【WCH以太网接口系列芯片】CH9121\9120、CH395\392以太网系列芯片的硬件电路注意事项

    本篇基于沁恒微电子官方的以太网接口芯片的DEMO参考原理图进行分析,对一些注意事项进行标注,如果硬件设计上出现问题可以对照参考. CH912x系列: 1.CH9121:建议设计中可以将31脚RUN脚预 ...

  6. #dp#洛谷 2679 子串

    题目 有两个仅包含小写英文字母的字符串 \(A\) 和 \(B\). 现在要从字符串 \(A\) 中取出 \(k\) 个互不重叠的非空子串,然后把这 \(k\) 个子串按照其在字符串 \(A\) 中出 ...

  7. Python实现聊天机器人接口封装部署

    一.前言说明 博客声明:此文链接地址https://www.cnblogs.com/Vrapile/p/12427326.html,请尊重原创,未经允许禁止转载!!! 1. 功能简述 (1)将chat ...

  8. 【直播回顾】如何成为一名优秀的OpenHamrony贡献者?

    5月18日晚上19点,战"码"先锋第一期直播<如何成为一名优秀的OpenHamrony 贡献者?>,在OpenHarmony社群内成功举行. 本期课程,由润和资深软件开 ...

  9. Java 异常处理与正则表达式详解,实例演练及最佳实践

    Java 异常 - Try...Catch 在 Java 代码执行期间,可能会发生各种错误,包括程序员编码错误.用户输入错误以及其他不可预料的状况. 当错误发生时,Java 通常会停止并生成错误消息, ...

  10. amcap使用方法

    1.选择设备 device 里面显示的是设备,分割线上面是视频设备,分割线下面是音频设备 2.打开图像 options > Preview  勾选上就是打开视频,再次点击取消勾线就是关闭视频 3 ...