利用Java获取磁盘基本信息

利用Java获取磁盘基本信息

Denvo 树犹如此,人何以堪

之前想写一个小的练手项目的时候突然有对这个的需求,但是网上全是到处搬运的错误的、不完整的代码,要不就是只给列个根目录出来…最后找了半天发现JDK本身就支持这个,于是就写出来分享一下。

完整代码

仅展示测试代码,实际使用时可能还需要改动。
测试环境:

  • 操作系统:Windows 10 22H2
  • Java版本:17
  • JDK:GraalVM 17.0.7+8.1(Hotspot模式)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
package main;

import java.io.IOException;
import java.nio.file.FileStore;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
import java.text.DecimalFormat;
import java.util.HashMap;

/**
* 使用Java获取磁盘基本信息.
* @author Denvo
*/
public class Main {
public static void main(String[] args) {
System.out.print(\"\n");
Iterable roots = FileSystems.getDefault().getRootDirectories(); //获取所有的磁盘的根目录.
for (Path root : roots) {
System.out.println(root.toString() + "信息:" + getDiskInfo(root)); //getDiskInfo()方法在下面实现.
}
}

/**
* 根据卷根目录获取卷的信息.
* @param root 根目录,如"C:\","D:\"
* @return 包含卷的信息的HashMap.
*/
private static HashMap getDiskInfo(Path root) {
HashMap result = new HashMap(8);
try {
FileStore fs = Files.getFileStore(root);
result.put("卷标", fs.name());
result.put("文件存储类型", fs.type());
result.put("只读", String.valueOf(fs.isReadOnly()));
result.put("总容量", autoUnitConversion(fs.getTotalSpace())); //autoUnitConversion()方法在下面实现.
result.put("可用容量", autoUnitConversion(fs.getUsableSpace()));
result.put("每个扇区大小", fs.getBlockSize() + " Bytes");
//以下仅Windows可用.
result.put("可移动", fs.getAttribute("volume:isRemovable").toString());
result.put("是否为CD-ROM", fs.getAttribute("volume:isCdrom").toString());
} catch (IOException e) {
e.printStackTrace();
}
return result;
}

/**
* 单位转换,从Byte转换成Byte,KB,MB,GB,TB,PB,EB等.
* @param bytesSize 原始大小(Byte)
* @return 换算之后的大小(自动添加单位)
*/
private static String autoUnitConversion(long bytesSize) {
if (bytesSize < 0) {
return "0";
} else {
double before = bytesSize;
double after;
for (int i = 0; i < 7; i++) {
after = before / 1024;
if (after < 1) {
String unit = switch (i) {
case 0 -> " Bytes";
case 1 -> " KB";
case 2 -> " MB";
case 3 -> " GB";
case 4 -> " TB";
case 5 -> " PB";
case 6 -> " EB";
default -> null;
};
return new DecimalFormat("#.##").format(before) + unit; //这里设置保留2位小数.
} else {
before = after;
}
}
return "8 EB或更大"; //long类型的最大值换算过来最大只有8EB.(正常情况下都应该从上面for循环中return.)
}
}
}

代码运行结果

我的电脑目前的磁盘有如下,其中G盘到J盘都是U盘。

在Explorer中看到的磁盘
在Explorer中看到的磁盘

以上代码的运行结果如下:

1
2
3
4
5
6
7
8
9
10
11


C:\\信息:{文件存储类型=NTFS, 总容量=223.15 GB, 可用容量=93.87 GB, 可移动=false, 是否为CD-ROM=false, 每个扇区大小=512 Bytes, 卷标=DenvosWindows, 只读=false}
D:\\信息:{文件存储类型=NTFS, 总容量=447.13 GB, 可用容量=340.74 GB, 可移动=false, 是否为CD-ROM=false, 每个扇区大小=512 Bytes, 卷标=SSD_Data, 只读=false}
E:\\信息:{文件存储类型=NTFS, 总容量=931.51 GB, 可用容量=455.83 GB, 可移动=false, 是否为CD-ROM=false, 每个扇区大小=512 Bytes, 卷标=DenvosData, 只读=false}
F:\\信息:{文件存储类型=NTFS, 总容量=1.82 TB, 可用容量=809.44 GB, 可移动=false, 是否为CD-ROM=false, 每个扇区大小=512 Bytes, 卷标=HDD_Data, 只读=false}
G:\\信息:{文件存储类型=FAT, 总容量=125.7 MB, 可用容量=115.87 MB, 可移动=true, 是否为CD-ROM=false, 每个扇区大小=512 Bytes, 卷标=, 只读=false}
H:\\信息:{文件存储类型=NTFS, 总容量=29.3 GB, 可用容量=5.59 GB, 可移动=true, 是否为CD-ROM=false, 每个扇区大小=512 Bytes, 卷标=, 只读=false}
I:\\信息:{文件存储类型=NTFS, 总容量=57.73 GB, 可用容量=31.68 GB, 可移动=true, 是否为CD-ROM=false, 每个扇区大小=512 Bytes, 卷标=KINGSTON, 只读=false}
J:\\信息:{文件存储类型=exFAT, 总容量=14.52 GB, 可用容量=7.5 GB, 可移动=true, 是否为CD-ROM=false, 每个扇区大小=512 Bytes, 卷标=Ventoy, 只读=false}

代码分析

实现功能的代码主要在getDiskInfo()方法中。首先通过FileStore fs = Files.getFileStore(Path root);来获取一个FileStore对象,然后通过这个对象来获取磁盘的相应信息的。

上面的代码中创建的fs对象的实现在java.base包中的sun.nio.fs.WindowsFileStore类,而这个类又继承了来自同一个包的抽象类java.nio.file.FileStore类。上面的代码中获取磁盘信息的方法实际上都是使用了被WindowsFileStore类重写的、来自FileSotre类中的方法。

WindowsFileSotre类的实现中,主要使用了java.base包中的sun.nio.fs.WindowsNativeDispatcher类中的方法,而这个类有很多方法都是native方法,即使用了JNI调用了位于%JAVA_HOME%/bin目录中的net.dllnio.dll两个dll中C/C++的方法(JDK文档说nio.dll需要net.dll作为依赖)

例如获取这个磁盘是否可移动的方法fs.getAttribute("volume:isRemovable")实际上调用了nio.dll中的方法Java_sun_nio_fs_WindowsNativeDispatcher_GetDriveType0,相对虚拟地址在00006078

  • 标题: 利用Java获取磁盘基本信息
  • 作者: Denvo
  • 创建于 : 2024-01-20 13:41:20
  • 更新于 : 2026-01-25 17:29:40
  • 链接: https://www.denvoshome.xyz/posts/Java-getDiskInfo/
  • 版权声明: 本文章采用 CC BY-SA 4.0 进行许可。
评论
目录
利用Java获取磁盘基本信息