- 在很多场景中需要获取到终端设备的一些硬件信息等,获取的字段如下:
返回参数
参数 | 含义 | 备注 |
---|---|---|
systemName | 系统名称 | |
remoteIp | 公网ip | |
localIp | 本地ip | 取IPV4 |
mac | mac地址 | 去掉地址中的"-“或”:"进行记录 |
cpuSerial | cpu序列号 | |
hardSerial | 硬盘序列号 | |
drive | 盘符 | C |
fileSystem | 分区格式 | NTFS |
partitionSize | 分区容量 | 119G |
systemDisk | 系统盘卷标号 | |
pcName | PC终端设备名称 | |
pcSerial | PC终端设备序列号 | 仅Mac系统有,其余系统返回"null" |
public final class HardInfoUtils {
private static final Logger LOGGER = LoggerFactory.getLogger(HardInfoUtils.class);
/**
* 获取系统名称-systemName
*
* @return 系统名称
*/
public static String getSystemName() {
return System.getProperty("os.name");
}
/**
* 获取本地IP-localIp
*
* @return 本机 IP 地址
* @throws RuntimeException 如果无法获取 IP 地址
*/
public static String getLocalIp() {
String os = System.getProperty("os.name").toLowerCase();
try {
if (os.contains("win")) {
// Windows 系统:使用 WMI 查询 IP 地址
return getWindowsLocalIp();
} else if (os.contains("nix") || os.contains("nux") || os.contains("aix")) {
// Linux 系统:使用 ifconfig 命令
return getLinuxLocalIp();
} else if (os.contains("mac")) {
// MacOS 系统:使用 ifconfig 命令
return getMacLocalIp();
} else {
throw new RuntimeException("Unsupported operating system: " + os);
}
} catch (Exception e) {
throw new RuntimeException("Failed to get localIp", e);
}
}
/**
* 获取公网 IP
*
* @return 公网 IP 地址,如果获取失败或格式不正确则返回 null
*/
public static String getRemoteIp() {
String os = System.getProperty("os.name").toLowerCase();
String command = "curl ifconfig.me";
if (os.contains("win")) {
return executeWindowsCommand(command, ip -> {
if (ip != null && isValidIp(ip)) {
return ip.trim();
} else {
LOGGER.error("IP format is incorrect or null: {}", ip);
return null;
}
});
} else {
return executeCommandAndParseOutput(command, ip -> {
if (ip != null && isValidIp(ip)) {
return ip.trim();
} else {
LOGGER.error("IP format is incorrect or null: {}", ip);
return null;
}
});
}
}
/**
* Windows 系统:获取本地 IP 地址
*
* @return 本地 IP 地址
*/
private static String getWindowsLocalIp() {
String command = "wmic nicconfig where IPEnabled=true get IPAddress";
return executeWindowsCommand(command, line -> {
if (line.contains(".")) {
String[] parts = line.split(",");
for (String part : parts) {
part = part.replaceAll("[{}\"]", "").trim();
if (isValidIp(part)) {
return part;
}
}
}
return null;
});
}
/**
* 检查 IP 地址是否有效
*
* @param ip IP 地址
* @return 是否有效
*/
private static boolean isValidIp(String ip) {
String ipv4Regex = "^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?).){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$";
Pattern pattern = Pattern.compile(ipv4Regex);
Matcher matcher = pattern.matcher(ip);
return matcher.matches();
}
/**
* Linux 系统:获取本地 IP 地址
*
* @return 本地 IP 地址
*/
private static String getLinuxLocalIp() {
String command =
"ifconfig | grep -E 'flags=|inet |broadcast ' | grep -i RUNNING -A 1 | grep 'inet ' | grep -m 1 " +
"'broadcast ' | awk '{print $2}'";
return executeCommandAndParseOutput(command, line -> line);
}
/**
* MacOS 系统:获取本地 IP 地址
*
* @return 本地 IP 地址
*/
private static String getMacLocalIp() {
String command =
"ifconfig | grep -E 'flags=|inet |broadcast ' | grep -i RUNNING -A 1 | grep 'inet ' | grep -m 1 " +
"'broadcast ' | awk '{print $2}'";
return executeCommandAndParseOutput(command, line -> line);
}
/**
* 执行 Windows 命令并解析输出
*
* @param command 命令
* @param outputProcessor 输出处理函数
* @return 处理后的输出结果
* @throws IOException IO 异常
*/
private static String executeWindowsCommand(String command, Function<String, String> outputProcessor) {
try {
Process process = Runtime.getRuntime().exec(command);
try (BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()))) {
String line;
while ((line = reader.readLine()) != null) {
String result = outputProcessor.apply(line.trim());
if (result != null) {
return result;
}
}
}
} catch (IOException e) {
throw new RuntimeException("Failed to execute command: " + command, e);
}
return null;
}
/**
* Linux或MacOS下执行命令并解析输出
*
* @param command 命令
* @return 输出结果
*/
private static String executeCommandAndParseOutput(String command, Function<String, String> outputProcessor) {
try {
Process process = Runtime.getRuntime().exec(new String[]{"sh", "-c", command});
try (BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()))) {
String line;
while ((line = reader.readLine()) != null) {
if (!line.trim().isEmpty()) {
String out = outputProcessor.apply(line.trim());
if (out != null) {
return out;
}
}
}
}
} catch (IOException e) {
throw new RuntimeException("Failed to execute command: " + command, e);
}
return null;
}
/**
* 获取本机 MAC 地址-mac
*
* @return 本机 MAC 地址
*/
public static String getMac() {
String os = System.getProperty("os.name").toLowerCase();
try {
if (os.contains("win")) {
// Windows 系统:使用 WMI 查询 MAC 地址
return formatMac(getWindowsMac());
} else if (os.contains("nix") || os.contains("nux") || os.contains("aix")) {
// Linux 系统:使用 ifconfig 命令
return formatMac(getLinuxMac());
} else if (os.contains("mac")) {
// MacOS 系统:使用 ifconfig 命令
return formatMac(getMacOSMac());
} else {
throw new RuntimeException("Unsupported operating system: " + os);
}
} catch (Exception e) {
throw new RuntimeException("Failed to get MAC address", e);
}
}
/**
* 格式化 MAC 地址为无分隔符的形式
*
* @param mac MAC 地址
* @return 无分隔符的 MAC 地址
*/
private static String formatMac(String mac) {
if (mac == null || mac.isEmpty()) {
return "";
}
// 移除所有分隔符(如 ":", "-")
return mac.replaceAll("[:\\-]", "");
}
/**
* Windows 系统:获取 MAC 地址
*
* @return MAC 地址
*/
private static String getWindowsMac() {
// 筛选出物理适配器,并且是已启用的状态
String command = "wmic nic where \"PhysicalAdapter=True and NetEnabled=True\" get MACAddress /format:value";
return executeWindowsCommand(command, line -> {
if (line.startsWith("MACAddress=") && line.length() > "MACAddress=".length()) {
// 清除前缀
String macAddress = line.substring("MACAddress=".length()).trim();
return macAddress.replace(":", "-");
}
return null;
});
}
/**
* Linux 系统:获取 MAC 地址
*
* @return MAC 地址
*/
private static String getLinuxMac() {
String command =
"ifconfig | grep -E 'flags=|inet |broadcast |ether ' | grep -i RUNNING -A 2 | grep -A 1 -E 'broadcast" +
" " + "|inet ' | grep -m 1 'ether ' | awk '{print $2}'";
return executeCommandAndParseOutput(command, line -> line);
}
/**
* MacOS 系统:获取 MAC 地址
*
* @return MAC 地址
*/
private static String getMacOSMac() {
String command =
"ifconfig | grep -E 'flags=|inet |broadcast |ether ' | grep -i RUNNING -A 2 | grep -B 1 -E 'broadcast" +
" " + "|inet ' | grep -m 1 'ether ' | awk '{print $2}'";
return executeCommandAndParseOutput(command, line -> line);
}
/**
* 获取CPU序列号-cpuSerial
*
* @return CPU 序列号
*/
public static String getCpuSerial() {
String os = System.getProperty("os.name").toLowerCase();
try {
if (os.contains("win")) {
// Windows 系统:使用 wmic 命令获取 CPU 序列号
return getWindowsCpuSerial();
} else if (os.contains("nix") || os.contains("nux") || os.contains("aix")) {
// Linux 系统:使用 dmidecode 命令获取 CPU 序列号
return getLinuxCpuSerial();
} else if (os.contains("mac")) {
// macOS 系统:使用 system_profiler 命令获取 CPU 序列号
return getMacCpuSerial();
} else {
throw new UnsupportedOperationException("Unsupported operating system: " + os);
}
} catch (Exception e) {
throw new RuntimeException("Failed to get cpuSerial", e);
}
}
/**
* Windows 系统:获取 CPU 序列号
*
* @return CPU 序列号
*/
private static String getWindowsCpuSerial() {
String command = "wmic cpu get ProcessorId";
return executeWindowsCommand(command, line -> {
if (!line.isEmpty() && !line.contains("ProcessorId")) {
return line;
}
return null;
});
}
/**
* Linux 系统:获取 CPU 序列号
*
* @return CPU 序列号
*/
private static String getLinuxCpuSerial() {
String command = "dmidecode -t 4 | grep -m 1 ID | awk '{print $2$3$4$5$6$7$8$9}'";
return executeCommandAndParseOutput(command, line -> {
// 去掉所有空格
String cpuSerial = line.replaceAll("\\s+", "");
// 如果 CPU 序列号全为 0,则返回 null
if ("0000000000000000".equals(cpuSerial)) {
return null;
}
return cpuSerial;
});
}
/**
* macOS 系统:获取 CPU 序列号
*
* @return CPU 序列号
*/
private static String getMacCpuSerial() {
String command = "system_profiler SPHardwareDataType | grep -m 1 'Serial Number' | awk '{print $4}'";
return executeCommandAndParseOutput(command, line -> {
// 去掉所有空格
return line.trim().replaceAll("\\s+", "");
});
}
/**
* 获取硬盘序列号-hardSerial
*
* @return 硬盘序列号
*/
public static String getHardSerial() {
String os = System.getProperty("os.name").toLowerCase();
try {
if (os.contains("win")) {
// Windows 系统
return getWindowsHardSerial();
} else if (os.contains("nix") || os.contains("nux") || os.contains("aix")) {
// Linux 系统
return getLinuxHardSerial();
} else if (os.contains("mac")) {
// macOS 系统
return getMacHardSerial();
} else {
throw new UnsupportedOperationException("Unsupported operating system: " + os);
}
} catch (Exception e) {
throw new RuntimeException("Failed to get hardSerial", e);
}
}
/**
* Windows 系统:获取硬盘序列号
*
* @return 硬盘序列号,如:6479_A75B_B090_09E0
*/
private static String getWindowsHardSerial() {
String command = "wmic diskdrive get serialnumber";
return executeWindowsCommand(command, line -> {
if (!line.trim().isEmpty() && !line.contains("SerialNumber")) {
// 去掉末尾的点(如果存在)
return line.trim().endsWith(".") ? line.trim().substring(0, line.length() - 1) : line.trim();
}
return null;
});
}
/**
* Linux 系统:获取硬盘序列号
*
* @return 硬盘序列号,如:ac7b3398-162e-4775-b
*/
private static String getLinuxHardSerial() {
// Linux amd 执行后:SERIAL=""
String command =
"lsblk -p -P -o NAME,SERIAL,UUID,TYPE,MOUNTPOINT | grep -i boot -B 1 | grep -i disk | awk '{print $2}'";
return executeCommandAndParseOutput(command, line -> {
String result = line.trim().replace("SERIAL=", "").replace("\"", "");
// 去掉末尾的点(如果存在)
if (result.endsWith(".")) {
result = result.substring(0, result.length() - 1);
}
// 如果序列号为空,返回 null
return result.isEmpty() ? null : result;
});
}
/**
* macOS 系统:获取硬盘序列号
*
* @return 硬盘序列号
*/
private static String getMacHardSerial() {
String command = "system_profiler SPHardwareDataType | grep -m 1 'Hardware UUID' | awk '{print $3}'";
return executeCommandAndParseOutput(command, line -> {
String result = line.trim();
// 去掉末尾的点(如果存在)
if (result.endsWith(".")) {
result = result.substring(0, result.length() - 1);
}
return result;
});
}
/**
* 获取系统盘盘符-drive
*
* @return 系统盘盘符,如:C 或 /dev/sda1
* @throws RuntimeException 获取失败时抛出异常
*/
public static String getDrive() {
String os = System.getProperty("os.name").toLowerCase();
try {
if (os.contains("win")) {
// Windows 系统
return getWindowsDrive();
} else if (os.contains("nix") || os.contains("nux") || os.contains("aix")) {
// Linux 系统
return getLinuxDrive();
} else if (os.contains("mac")) {
// macOS 系统
return getMacDrive();
} else {
throw new UnsupportedOperationException("Unsupported operating system: " + os);
}
} catch (Exception e) {
throw new RuntimeException("Failed to get drive", e);
}
}
/**
* Windows 系统:获取盘符
*
* @return 盘符,如:C
*/
private static String getWindowsDrive() {
// 获取系统盘盘符(如 C:)
String systemDrive = System.getenv("SystemDrive");
if (systemDrive == null || systemDrive.isEmpty()) {
LOGGER.error("SystemDrive environment variable is empty");
return null;
}
// 去掉冒号
return systemDrive.replace(":", "");
}
/**
* Linux 系统:获取盘符
*
* @return 盘符,如:/dev/sda1
*/
private static String getLinuxDrive() {
String command =
"lsblk -p -P -o NAME,PARTUUID,FSTYPE,SIZE,UUID,TYPE,MOUNTPOINT | grep -E '/boot\"$' | grep -i part | " +
"awk " + "'{print $1,$2,$3,$4}'";
return executeCommandAndParseOutput(command, line -> {
String[] split = line.split("\"");
return split.length > 1 ? split[1] : null;
});
}
/**
* macOS 系统:获取盘符
*
* @return 盘符
*/
private static String getMacDrive() {
String command = "system_profiler SPSoftwareDataType | grep -m 1 'Boot Volume'";
return executeCommandAndParseOutput(command, line -> {
String[] split = line.split(": ");
return split.length > 1 ? split[1] : null;
});
}
/**
* 获取系统盘分区格式-fileSystem
*
* @return 系统盘分区格式,如:NTFS 或 xf4
* @throws RuntimeException 如果无法获取分区格式
*/
public static String getFileSystem() {
String os = System.getProperty("os.name").toLowerCase();
try {
if (os.contains("win")) {
// Windows 系统
return getWindowsFileSystem();
} else if (os.contains("nix") || os.contains("nux") || os.contains("aix")) {
// Linux 系统
return getLinuxFileSystem();
} else if (os.contains("mac")) {
// macOS 系统
return getMacFileSystem();
} else {
throw new UnsupportedOperationException("Unsupported operating system: " + os);
}
} catch (Exception e) {
throw new RuntimeException("Failed to get fileSystem", e);
}
}
/**
* Windows 系统:获取分区格式
*
* @return 分区格式,如:NTFS
*/
private static String getWindowsFileSystem() {
// 获取系统盘盘符(如 C:)
String systemDrive = System.getenv("SystemDrive");
if (systemDrive == null || systemDrive.isEmpty()) {
LOGGER.error("SystemDrive environment variable is empty");
return null;
}
// 获取系统盘的分区信息
String command = "wmic logicaldisk where deviceid='" + systemDrive + "' get filesystem";
return executeWindowsCommand(command, line -> {
if (!line.isEmpty() && !line.contains("FileSystem")) {
return line;
}
return null;
});
}
/**
* Linux 系统:获取分区格式
*
* @return 分区格式
*/
private static String getLinuxFileSystem() {
String command =
"lsblk -p -P -o NAME,PARTUUID,FSTYPE,SIZE,UUID,TYPE,MOUNTPOINT | grep -E '/boot\"$' | grep -i part | " +
"awk " + "'{print $1,$2,$3,$4}'";
return executeCommandAndParseOutput(command, line -> {
String[] split = line.split("\"");
return split.length > 5 ? split[5] : null;
});
}
/**
* macOS 系统:获取分区格式
*
* @return 分区格式
*/
private static String getMacFileSystem() {
String command = "system_profiler SPStorageDataType | grep -w -A 5 -B 1 'Mount Point: /'";
return executeCommandAndParseOutput(command, line -> {
String number = "";
String[] lines = line.split("\n");
for (String l : lines) {
l = l.trim();
if (l.startsWith("File System:")) {
String[] split = l.split(" ");
if (split.length > 2) {
number = split[2];
}
}
}
return number.isEmpty() ? null : number;
});
}
/**
* 获取系统盘分区容量
*
* @return 系统盘分区容量,如:119G
* @throws RuntimeException 如果无法获取分区容量
*/
public static String getPartitionSize() {
String os = System.getProperty("os.name").toLowerCase();
try {
if (os.contains("win")) {
// Windows 系统
return getWindowsPartitionSize();
} else if (os.contains("nix") || os.contains("nux") || os.contains("aix")) {
// Linux 系统
return getLinuxPartitionSize();
} else if (os.contains("mac")) {
// macOS 系统
return getMacPartitionSize();
} else {
throw new UnsupportedOperationException("Unsupported operating system: " + os);
}
} catch (Exception e) {
throw new RuntimeException("Failed to get partition size", e);
}
}
/**
* Windows 系统:获取分区容量
*
* @return 分区容量
*/
private static String getWindowsPartitionSize() {
// 获取系统盘盘符(如 C:)
String systemDrive = System.getenv("SystemDrive");
if (systemDrive == null || systemDrive.isEmpty()) {
LOGGER.error("SystemDrive environment variable is empty");
return null;
}
// 获取系统盘的分区信息
String command = "wmic logicaldisk where deviceid='" + systemDrive + "' get size";
return executeWindowsCommand(command, line -> {
if (!line.isEmpty() && !line.contains("Size")) {
long sizeBytes = Long.parseLong(line);
return (sizeBytes / 1024 / 1024 / 1024) + "G";
}
return null;
});
}
/**
* Linux 系统:获取分区容量
*
* @return 分区容量
*/
private static String getLinuxPartitionSize() {
String command =
"lsblk -p -P -o NAME,PARTUUID,FSTYPE,SIZE,UUID,TYPE,MOUNTPOINT | grep -E '/boot\"$' | grep -i part | " +
"awk " + "'{print $1,$2,$3,$4}'";
return executeCommandAndParseOutput(command, output -> {
String[] split = output.split("\"");
return split.length > 7 ? split[7] : null;
});
}
/**
* macOS 系统:获取分区容量
*
* @return 分区容量
*/
private static String getMacPartitionSize() {
String command = "system_profiler SPStorageDataType | grep -w -A 5 -B 1 'Mount Point: /'";
return executeCommandAndParseOutput(command, line -> {
String size = "";
String[] lines = line.split("\n");
for (String l : lines) {
l = l.trim();
if (l.startsWith("Capacity:")) {
String[] split = l.split(" ");
if (split.length > 1) {
size = split[1] + "G";
}
}
}
return size;
});
}
/**
* 获取系统盘卷标号-systemDisk
*
* @return 系统盘卷标号
*/
public static String getSystemDisk() {
String os = System.getProperty("os.name").toLowerCase();
try {
if (os.contains("win")) {
// Windows 系统
return getWindowsSystemDisk();
} else if (os.contains("nix") || os.contains("nux") || os.contains("aix")) {
// Linux 系统
return getLinuxSystemDisk();
} else if (os.contains("mac")) {
// macOS 系统
return getMacSystemDisk();
} else {
throw new UnsupportedOperationException("Unsupported operating system: " + os);
}
} catch (Exception e) {
throw new RuntimeException("Failed to get systemDisk", e);
}
}
/**
* Windows 系统:获取系统盘卷标号
*
* @return 系统盘卷标号,格式为 "XXXX-XXXX",如:8AD0-CC8B
*/
private static String getWindowsSystemDisk() {
// 获取系统盘盘符(如 C:)
String systemDrive = System.getenv("SystemDrive");
if (systemDrive == null || systemDrive.isEmpty()) {
LOGGER.error("SystemDrive environment variable is empty");
return null;
}
// 获取系统盘的卷标号
String command = "wmic logicaldisk where deviceid='" + systemDrive + "' get VolumeSerialNumber";
return executeWindowsCommand(command, line -> {
if (!line.isEmpty() && !line.contains("VolumeSerialNumber")) {
if (line.length() == 8) {
// 格式化为 XXXX-XXXX
return line.substring(0, 4) + "-" + line.substring(4);
}
}
return null;
});
}
/**
* Linux 系统:获取系统盘卷标号
*
* @return 系统盘卷标号
*/
private static String getLinuxSystemDisk() {
// 使用 lsblk 命令获取系统盘卷标号
// Linux amd执行后:UUID="" LABEL=""
String command =
"lsblk -p -P -o NAME,UUID,LABEL,TYPE,MOUNTPOINT | grep -i boot -B 1 | grep -i disk | awk '{print $2," +
"$3}'";
return executeCommandAndParseOutput(command, line -> {
String[] parts = line.trim().split("\"");
if (parts.length >= 4) {
// UUID
String uuid = parts[1];
// LABEL
String label = parts[3];
// 返回 UUID 或 LABEL
return !uuid.isEmpty() ? uuid : label;
}
return null;
});
}
/**
* macOS 系统:获取系统盘卷标号
*
* @return 系统盘卷标号
*/
private static String getMacSystemDisk() {
String command = "system_profiler SPStorageDataType | grep -w -A 5 -B 1 'Mount Point: /'";
return executeCommandAndParseOutput(command, line -> {
String number = "";
String[] lines = line.split("\n");
for (String l : lines) {
l = l.trim();
if (l.startsWith("Volume UUID:")) {
String[] split = l.split(" ");
if (split.length > 2) {
number = split[2];
}
}
}
return number.isEmpty() ? null : number;
});
}
/**
* 获取PC终端设备名称-pcName
*
* @return PC终端设备名称
*/
public static String getPcName() {
String os = System.getProperty("os.name").toLowerCase();
try {
if (os.contains("win")) {
// Windows 系统:使用 hostname 命令获取设备名称
String command = "hostname";
return executeWindowsCommand(command, line -> line.isEmpty() ? null : line);
} else if (os.contains("nix") || os.contains("nux") || os.contains("aix")) {
// Linux 系统:使用 hostname 命令获取设备名称
return executeCommandAndParseOutput("hostname", line -> line);
} else if (os.contains("mac")) {
// MacOS 系统:使用 scutil 命令获取设备名称
return executeCommandAndParseOutput("scutil --get ComputerName", line -> line);
} else {
throw new RuntimeException("Unsupported operating system: " + os);
}
} catch (Exception e) {
throw new RuntimeException("Failed to get pcName.", e);
}
}
/**
* 获取PC终端设备序列号(仅 Mac 系统有,其他系统返回 "null")
*
* @return PC 终端设备序列号,如果获取失败或非 Mac 系统则返回 "null"
*/
public static String getPcSerial() {
String os = System.getProperty("os.name").toLowerCase();
if (!os.contains("mac")) {
// 非 Mac 系统直接返回 "null"
return "null";
}
try {
// MacOS 系统:使用 system_profiler 命令获取设备序列号
String command = "system_profiler SPHardwareDataType | grep -m 1 'Provisioning UDID' | awk '{print $3}'";
return executeCommandAndParseOutput(command, line -> line);
} catch (Exception e) {
throw new RuntimeException("Failed to get pcSerial on MacOS.", e);
}
}
}
- 测试下本地Windows
public class HardInfoUtilsTest {
public static void main(String[] args) {
System.out.println("systemName: " + HardInfoUtils.getSystemName());
System.out.println("localIp: " + HardInfoUtils.getLocalIp());
System.out.println("remoteIp: " + HardInfoUtils.getRemoteIp());
System.out.println("mac: " + HardInfoUtils.getMac());
System.out.println("cpuSerial: " + HardInfoUtils.getCpuSerial());
System.out.println("hardSerial: " + HardInfoUtils.getHardSerial());
System.out.println("drive: " + HardInfoUtils.getDrive());
System.out.println("fileSystem: " + HardInfoUtils.getFileSystem());
System.out.println("partitionSize: " + HardInfoUtils.getPartitionSize());
System.out.println("systemDisk: " + HardInfoUtils.getSystemDisk());
System.out.println("pcName: " + HardInfoUtils.getPcName());
System.out.println("pcSerial: " + HardInfoUtils.getPcSerial());
}
}