263 lines
6.8 KiB
Java
263 lines
6.8 KiB
Java
package com.imyeyu.utils;
|
||
|
||
import com.sun.management.OperatingSystemMXBean;
|
||
|
||
import java.awt.Desktop;
|
||
import java.awt.Toolkit;
|
||
import java.awt.datatransfer.DataFlavor;
|
||
import java.awt.datatransfer.StringSelection;
|
||
import java.io.BufferedReader;
|
||
import java.io.File;
|
||
import java.io.IOException;
|
||
import java.io.InputStreamReader;
|
||
import java.lang.management.ManagementFactory;
|
||
import java.util.Comparator;
|
||
|
||
/**
|
||
* @author 夜雨
|
||
* @version 2023-08-07 11:46
|
||
*/
|
||
public class OS {
|
||
|
||
/**
|
||
*
|
||
*
|
||
* @author 夜雨
|
||
* @since 2021-02-13 10:15
|
||
*/
|
||
public interface FileSystem {
|
||
|
||
/** 文件系统路径分隔符 FileSystem.separator */
|
||
String SEP = File.separator;
|
||
|
||
/** 文件名排序,优先文件和文件夹,次级名称 */
|
||
Comparator<File> COMPARATOR_FILE_NAME = (f1, f2) -> {
|
||
if (f1.isDirectory() && f2.isFile()) {
|
||
return -1;
|
||
} else {
|
||
if (f1.isFile() && f2.isDirectory()) {
|
||
return 1;
|
||
} else {
|
||
return f1.getName().compareToIgnoreCase(f2.getName());
|
||
}
|
||
}
|
||
};
|
||
}
|
||
|
||
/**
|
||
* 系统平台
|
||
*
|
||
* @author 夜雨
|
||
* @version 2024-06-22 14:41
|
||
*/
|
||
public enum Platform {
|
||
|
||
WINDOWS,
|
||
|
||
LINUX,
|
||
|
||
MAC
|
||
}
|
||
|
||
/** 运行时系统 */
|
||
public static final String NAME = System.getProperty("os.name");
|
||
|
||
/** true 为 Windows 系统 */
|
||
public static final boolean IS_WINDOWS = NAME.toLowerCase().contains("win");
|
||
|
||
/** true 为 Mac OSX 系统 */
|
||
public static final boolean IS_OSX = NAME.toLowerCase().contains("mac os x");
|
||
|
||
/** true 为 UNIX 系统 */
|
||
public static final boolean IS_UNIX = NAME.contains("nix") || NAME.contains("nux") || NAME.contains("mac");
|
||
|
||
/** 当前系统平台 */
|
||
public static final Platform PLATFORM = IS_WINDOWS ? Platform.WINDOWS : (IS_OSX ? Platform.MAC : Platform.LINUX);
|
||
|
||
/**
|
||
* 不处理异常执行命令
|
||
*
|
||
* @param command 命令
|
||
*/
|
||
public static void run(String command) {
|
||
try {
|
||
Runtime.getRuntime().exec(new String[] {command});
|
||
} catch (Exception e) {
|
||
throw new RuntimeException(e);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 终止程序时执行命令(主线程结束后)
|
||
*
|
||
* @param command 命令
|
||
*/
|
||
public static void runAfterShutdown(String command) {
|
||
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
|
||
try {
|
||
new ProcessBuilder(command).start();
|
||
} catch (IOException ignored) {
|
||
}
|
||
}));
|
||
}
|
||
|
||
/** @return 系统内存大小(单位:字节) */
|
||
public static Long getSystemMemorySize() {
|
||
return ((OperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean()).getTotalMemorySize();
|
||
}
|
||
|
||
/** Windows 系统禁用的字符 */
|
||
public static final Character[] INVALID_WINDOWS_SPECIFIC_CHARS = {'"', '*', ':', '<', '>', '?', '\\', '|', '/', 0x7F};
|
||
|
||
/** Unix 系统禁用的字符 */
|
||
public static final Character[] INVALID_UNIX_SPECIFIC_CHARS = {'\000'};
|
||
|
||
/**
|
||
* 文件名规则验证
|
||
*
|
||
* @param fileName 文件名
|
||
* @return true 为有效的
|
||
*/
|
||
public static boolean isValidFileName(String fileName) {
|
||
if (fileName == null || fileName.isEmpty() || 255 < fileName.length()) {
|
||
return false;
|
||
}
|
||
Character[] chars;
|
||
if (IS_WINDOWS) {
|
||
chars = INVALID_WINDOWS_SPECIFIC_CHARS;
|
||
} else if (IS_UNIX) {
|
||
chars = INVALID_UNIX_SPECIFIC_CHARS;
|
||
} else {
|
||
return true;
|
||
}
|
||
for (int i = 0; i < chars.length; i++) {
|
||
if (fileName.contains(chars[i].toString())) {
|
||
return false;
|
||
}
|
||
}
|
||
return true;
|
||
}
|
||
|
||
/**
|
||
* 调用系统资源管理器打开位置
|
||
*
|
||
* @param dir 文件
|
||
*/
|
||
public static void showInExplorer(File dir) {
|
||
if (dir == null || !dir.exists()) {
|
||
throw new IllegalArgumentException("dir is not found");
|
||
}
|
||
if (IS_WINDOWS) {
|
||
if (dir.isFile()) {
|
||
dir = dir.getParentFile();
|
||
}
|
||
run("explorer " + dir.getAbsolutePath() + FileSystem.SEP);
|
||
} else {
|
||
Desktop.getDesktop().browseFileDirectory(dir);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 调用系统资源管理器打开文件位置并选中
|
||
*
|
||
* @param files 文件列表
|
||
*/
|
||
public static void showAndSelectInExplorer(File... files) {
|
||
StringBuilder sb = new StringBuilder();
|
||
for (int i = 0; i < files.length; i++) {
|
||
sb.append('"').append(files[i].getAbsolutePath()).append('"').append(',');
|
||
}
|
||
if (IS_WINDOWS) {
|
||
run("explorer /select," + sb.substring(0, sb.length() - 1));
|
||
} else {
|
||
Desktop.getDesktop().browseFileDirectory(files[0]);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 检查某程序的某进程是否在运行(Windows 方法)
|
||
*
|
||
* @param appName 程序名
|
||
* @param processName 进程名
|
||
* @param excludeProcessName 排除名称
|
||
* @return true 为正在运行
|
||
* @throws Exception 异常
|
||
*/
|
||
public static boolean findProcess4Similarity(String appName, String processName, String... excludeProcessName) throws Exception {
|
||
return findProcess(appName, processName, true, .8F, excludeProcessName);
|
||
}
|
||
|
||
/**
|
||
* 检查某程序的某进程是否在运行(Windows 方法)
|
||
*
|
||
* @param appName 程序名
|
||
* @param processName 进程名
|
||
* @param similarity true 为启用相似度搜索
|
||
* @param similarityRate 相似度达到多少判定为 true
|
||
* @param excludeProcessName 排除名称
|
||
* @return true 为正在运行
|
||
* @throws Exception 异常
|
||
*/
|
||
public static boolean findProcess(String appName, String processName, boolean similarity, float similarityRate, String... excludeProcessName) throws Exception {
|
||
Process proc = Runtime.getRuntime().exec("tasklist -v -fi " + '"' + "imagename eq " + appName + '"');
|
||
BufferedReader br = new BufferedReader(new InputStreamReader(proc.getInputStream()));
|
||
|
||
int titleStart = -1; // 线程名起始字符
|
||
String line;
|
||
whi1e:
|
||
while ((line = br.readLine()) != null) {
|
||
if (titleStart == -1) {
|
||
if (line.startsWith("===")) {
|
||
titleStart = line.lastIndexOf(" ");
|
||
}
|
||
continue;
|
||
}
|
||
if (line.startsWith(appName)) {
|
||
// 排除名
|
||
if (excludeProcessName != null) {
|
||
for (int i = 0; i < excludeProcessName.length; i++) {
|
||
if (line.contains(excludeProcessName[i])) {
|
||
continue whi1e;
|
||
}
|
||
}
|
||
}
|
||
// 相似度匹配
|
||
if (similarity && titleStart < line.length()) {
|
||
String title = line.substring(titleStart).trim();
|
||
if (!title.equals("")) {
|
||
if (similarityRate < Text.similarityRatio(processName, title)) {
|
||
return true;
|
||
}
|
||
}
|
||
} else {
|
||
return line.contains(processName);
|
||
}
|
||
}
|
||
}
|
||
br.close();
|
||
return false;
|
||
}
|
||
|
||
/**
|
||
* 设置字符串到剪切板(复制)
|
||
*
|
||
* @param s 字符串
|
||
*/
|
||
public static void setIntoClipboard(String s) {
|
||
Toolkit.getDefaultToolkit().getSystemClipboard().setContents(new StringSelection(s), null);
|
||
}
|
||
|
||
/**
|
||
* 获取剪切版的字符串(粘贴)
|
||
*
|
||
* @return 剪切板字符串,如果剪切板没有字符串将返回空的字符串
|
||
*/
|
||
public static String getIntoClipboard() {
|
||
try {
|
||
return Toolkit.getDefaultToolkit().getSystemClipboard().getContents(null).getTransferData(DataFlavor.stringFlavor).toString();
|
||
} catch (Exception e) {
|
||
return "";
|
||
}
|
||
}
|
||
}
|