Java NIO 为我们提供了创建稀疏文件的选项
val path = Path("""E:\a""")
val fileChannel = FileChannel.open(
path,
StandardOpenOption.READ,
StandardOpenOption.WRITE,
StandardOpenOption.CREATE_NEW,
StandardOpenOption.SPARSE,
)
文档说,如果操作系统和文件系统支持,则会创建稀疏文件,但如果不支持,则会创建常规文件。
但我想知道操作系统+文件系统是否支持 SPARSE,以便我可以从我的应用程序中禁用某个功能。
您可以使用稀疏选项创建一个大小为 10 KB 的空文件,并检查它在文件系统上的实际大小。如果实际大小小于 10 KB,则支持稀疏。如果是 10KB - 则不支持。并检查后删除文件。
如果文件是稀疏文件,则意味着其物理大小/逻辑大小应小于 1。如果您可以计算出这个值,那么您就可以了解该文件是否是稀疏文件。
为此,您首先需要获取文件的物理大小。 Windows 和 Linux 应该使用不同的方法来计算该值。
没有直接的 API,因此您需要使用 ProcessBuilder:
对于Linux:
Path path = Paths.get(filePath);
File file = path.toFile();
Long physicalSize = 0;
// create and run the process
Process process = new ProcessBuilder("du", "-b",file.getAbsolutePath()).redirectErrorStream(true).start();
try (BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()))) {
String line = reader.readLine();
if (line != null) {
String[] parts = line.split("\\s+");
// take the value from return string should be something like: 9379 filename
physicalSize = Long.parseLong(parts[0]);
}
}
process.waitFor();
捕获物理大小后,您需要捕获文件的逻辑大小,只需这样做:
Path path = Paths.get(filePath);
long logicalSize = Files.size(path);
最后你可以使用这两个值来确定它是否是稀疏文件:
double sparseness = (double) physicalSize / logicalSize;
if (sparseness < 1) {
System.out.println("a sparse file");
} else {
System.out.println("not a sparse file");
}
根据本页,只有 3 个主要文件系统不支持稀疏文件:
另请注意,稀疏文件在不同文件系统上的创建方式不同。在 NTFS 上,您需要显式使文件稀疏。在其他文件系统上,文件会自动稀疏(如这个问题所示)。
在 Windows 上,
StandardOpenOption.SPARSE
标志用于 WindowsChannelFactory
:
// make the file sparse if needed
if (dwCreationDisposition == CREATE_NEW && flags.sparse) {
try {
DeviceIoControlSetSparse(handle);
} catch (WindowsException x) {
// ignore as sparse option is hint
}
}
NTFS 时调用会成功。
UnixChannelFactory
: 中被忽略
case SPARSE : /* ignore */ break;
对于除 HFS+ 之外的大多数文件系统,该文件将是稀疏的。
没有纯 Java 解决方案可以回答“文件系统是否支持稀疏文件”的问题。然而,实际上,只有旧版 MacOS 不支持。