RuntimeUtil
RuntimeUtil是Hutool中用于处理系统运行时相关操作的工具类,主要提供了系统命令执行、JVM信息获取、进程管理等功能。
# 功能介绍
- 系统命令执行:支持执行系统命令并获取结果,支持自定义编码、环境变量和工作目录
- 命令结果处理:提供多种结果获取方式,包括字符串和行列表
- 进程管理:支持销毁进程
- JVM信息获取:获取处理器数量、内存使用情况等
- JVM关闭钩子:添加JVM关闭时执行的钩子
- 进程ID获取:获取当前进程ID
# 核心方法
# 1. 系统命令执行
# execForStr(String... cmds)
执行系统命令,使用系统默认编码,返回字符串结果。
// 执行ls命令(Linux/macOS)
String result1 = RuntimeUtil.execForStr("ls", "-la");
// 执行dir命令(Windows)
String result2 = RuntimeUtil.execForStr("dir");
# execForStr(Charset, String... cmds)
执行系统命令,使用指定编码,返回字符串结果。
// 使用UTF-8编码执行命令
String result = RuntimeUtil.execForStr(CharsetUtil.UTF_8, "echo", "Hello, Hutool!");
# execForLines(String... cmds)
执行系统命令,使用系统默认编码,返回按行区分的结果列表。
// 执行ping命令
List<String> lines = RuntimeUtil.execForLines("ping", "hutool.cn");
for (String line : lines) {
Console.log(line);
}
# execForLines(Charset, String... cmds)
执行系统命令,使用指定编码,返回按行区分的结果列表。
// 使用GBK编码执行命令
List<String> lines = RuntimeUtil.execForLines(CharsetUtil.GBK, "dir");
# exec(String... cmds)
执行系统命令,返回Process对象。
// 执行命令,返回Process对象
Process process = RuntimeUtil.exec("echo", "Hello");
// 后续可以通过Process对象进行更多操作
# exec(String[] envp, String... cmds)
执行系统命令,指定环境变量。
// 指定环境变量执行命令
String[] envp = {"PATH=/usr/local/bin:" + System.getenv("PATH")};
Process process = RuntimeUtil.exec(envp, "echo", "$PATH");
# exec(String[] envp, File dir, String... cmds)
执行系统命令,指定环境变量和工作目录。
// 指定工作目录执行命令
File dir = new File("/tmp");
Process process = RuntimeUtil.exec(null, dir, "pwd");
# 2. 进程管理
# getResult(Process)
从Process对象获取命令执行结果,使用系统默认编码。
Process process = RuntimeUtil.exec("echo", "Hello");
String result = RuntimeUtil.getResult(process);
// 结果:"Hello\n"
# getResult(Process, Charset)
从Process对象获取命令执行结果,使用指定编码。
Process process = RuntimeUtil.exec("echo", "Hello");
String result = RuntimeUtil.getResult(process, CharsetUtil.UTF_8);
# getResultLines(Process)
从Process对象获取命令执行结果,按行区分,使用系统默认编码。
Process process = RuntimeUtil.exec("ls", "-la");
List<String> lines = RuntimeUtil.getResultLines(process);
# getResultLines(Process, Charset)
从Process对象获取命令执行结果,按行区分,使用指定编码。
Process process = RuntimeUtil.exec("ls", "-la");
List<String> lines = RuntimeUtil.getResultLines(process, CharsetUtil.UTF_8);
# getErrorResult(Process)
从Process对象获取命令执行异常结果,使用系统默认编码。
Process process = RuntimeUtil.exec("invalid_command");
String error = RuntimeUtil.getErrorResult(process);
# destroy(Process)
销毁进程。
Process process = RuntimeUtil.exec("sleep", "10");
// 执行一些操作后销毁进程
RuntimeUtil.destroy(process);
# 3. JVM信息获取
# getProcessorCount
获得JVM可用的处理器数量(一般为CPU核心数)。
int cpuCount = RuntimeUtil.getProcessorCount();
Console.log("CPU核心数:" + cpuCount);
# getFreeMemory
获得JVM中剩余的内存数,单位byte。
long freeMemory = RuntimeUtil.getFreeMemory();
Console.log("剩余内存:" + freeMemory + " byte");
# getTotalMemory
获得JVM已经从系统中获取到的总共的内存数,单位byte。
long totalMemory = RuntimeUtil.getTotalMemory();
Console.log("总内存:" + totalMemory + " byte");
# getMaxMemory
获得JVM中可以从系统中获取的最大的内存数,单位byte,以-Xmx参数为准。
long maxMemory = RuntimeUtil.getMaxMemory();
Console.log("最大内存:" + maxMemory + " byte");
# getUsableMemory
获得JVM最大可用内存,计算方法为:最大内存-总内存+剩余内存。
long usableMemory = RuntimeUtil.getUsableMemory();
Console.log("可用内存:" + usableMemory + " byte");
# getPid
获取当前进程ID。
int pid = RuntimeUtil.getPid();
Console.log("进程ID:" + pid);
# 4. JVM关闭钩子
# addShutdownHook
增加一个JVM关闭后的钩子,用于在JVM关闭时执行某些操作。
// 添加JVM关闭钩子,用于资源清理
RuntimeUtil.addShutdownHook(() -> {
Console.log("JVM正在关闭,执行资源清理...");
// 执行资源清理操作
});
# 应用场景
# 1. 系统命令执行
在需要执行系统命令并获取结果时,可以使用RuntimeUtil:
// 执行系统命令获取系统信息
String osInfo = RuntimeUtil.execForStr("uname", "-a");
Console.log("系统信息:" + osInfo);
// 执行命令获取磁盘使用情况
String diskUsage = RuntimeUtil.execForStr("df", "-h");
Console.log("磁盘使用情况:" + diskUsage);
# 2. 批量命令执行
在需要执行多个命令时,可以使用RuntimeUtil:
// 批量执行命令
List<String> commands = Arrays.asList(
"echo '开始执行批量命令'",
"ls -la",
"echo '批量命令执行完成'"
);
for (String cmd : commands) {
String result = RuntimeUtil.execForStr(cmd);
Console.log("命令:" + cmd);
Console.log("结果:" + result);
Console.log("----------------");
}
# 3. JVM资源监控
在需要监控JVM资源使用情况时,可以使用RuntimeUtil提供的内存相关方法:
// 定期监控JVM内存使用情况
ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
executor.scheduleAtFixedRate(() -> {
long freeMem = RuntimeUtil.getFreeMemory();
long totalMem = RuntimeUtil.getTotalMemory();
long maxMem = RuntimeUtil.getMaxMemory();
System.out.printf("内存使用情况:%.2f%% (%.2f MB / %.2f MB)\n",
(totalMem - freeMem) * 100.0 / totalMem,
(totalMem - freeMem) / 1024.0 / 1024.0,
maxMem / 1024.0 / 1024.0);
}, 0, 5, TimeUnit.SECONDS);
# 4. JVM关闭时的资源清理
在需要在JVM关闭时执行资源清理操作时,可以使用addShutdownHook方法:
// 创建一个资源管理器
class ResourceManager {
public void init() {
Console.log("资源初始化");
// 初始化资源
// 添加关闭钩子,在JVM关闭时清理资源
RuntimeUtil.addShutdownHook(this::cleanup);
}
private void cleanup() {
Console.log("资源清理");
// 执行资源清理操作
}
}
// 使用资源管理器
ResourceManager manager = new ResourceManager();
manager.init();
# 5. 进程管理
在需要执行外部进程并进行管理时,可以使用RuntimeUtil:
// 执行一个长时间运行的进程
Process process = RuntimeUtil.exec("tail", "-f", "/var/log/system.log");
// 读取进程输出
InputStream inputStream = process.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
String line;
while ((line = reader.readLine()) != null) {
Console.log("日志:" + line);
// 满足条件时停止进程
if (line.contains("ERROR")) {
RuntimeUtil.destroy(process);
break;
}
}
# 注意事项
- 命令执行安全:执行系统命令时要注意安全,避免命令注入攻击,尤其是当命令包含用户输入时。
- 编码问题:不同系统使用的默认编码可能不同,建议显式指定编码,避免乱码问题。
- 进程管理:执行命令后要及时销毁进程,避免资源泄漏。
- 异常处理:执行系统命令可能会抛出IO异常,需要进行适当的异常处理。
- 环境变量:在指定环境变量时,要注意环境变量的格式,正确的格式为"key=value"。
- 工作目录:在指定工作目录时,要确保目录存在,否则会抛出异常。
- JVM关闭钩子:添加的关闭钩子会在JVM正常关闭或强制关闭时执行,但在某些情况下(如使用kill -9命令)可能不会执行。
- 内存计算:内存相关方法返回的是JVM层面的内存使用情况,不是操作系统层面的。
- 处理器数量:getProcessorCount方法返回的是JVM可用的处理器数量,可能小于实际CPU核心数。
# 总结
RuntimeUtil是一个功能强大的系统运行时工具类,提供了丰富的系统命令执行和JVM管理功能。无论是执行系统命令、获取JVM信息还是管理JVM关闭钩子,RuntimeUtil都能提供简洁高效的解决方案。在使用RuntimeUtil时,需要注意命令执行安全、编码问题和资源管理,以确保代码的安全性和可靠性。