如何以编程方式知道文件系统是否支持稀疏文件

问题描述 投票:0回答:3

Java NIO 为我们提供了创建稀疏文件的选项

    val path = Path("""E:\a""")

    val fileChannel = FileChannel.open(
        path,
        StandardOpenOption.READ,
        StandardOpenOption.WRITE,
        StandardOpenOption.CREATE_NEW,
        StandardOpenOption.SPARSE,
    )

文档说,如果操作系统和文件系统支持,则会创建稀疏文件,但如果不支持,则会创建常规文件。

但我想知道操作系统+文件系统是否支持 SPARSE,以便我可以从我的应用程序中禁用某个功能。

java kotlin filesystems sparse-file java-nio
3个回答
0
投票

您可以使用稀疏选项创建一个大小为 10 KB 的空文件,并检查它在文件系统上的实际大小。如果实际大小小于 10 KB,则支持稀疏。如果是 10KB - 则不支持。并检查后删除文件。


0
投票

如果文件是稀疏文件,则意味着其物理大小/逻辑大小应小于 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");
            }

0
投票

稀疏文件和文件系统

根据本页,只有 3 个主要文件系统不支持稀疏文件:

  • HFS+(旧版 MacOS FS)
  • exFAT(用于 USB 闪存驱动器)
  • FAT32(非常旧的 Windows FS)

另请注意,稀疏文件在不同文件系统上的创建方式不同。在 NTFS 上,您需要显式使文件稀疏。在其他文件系统上,文件会自动稀疏(如这个问题所示)。

Java 如何创建稀疏文件

在 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 时调用会成功。

对于基于 Unix 的操作系统,该标志在

UnixChannelFactory
:

中被忽略
case SPARSE : /* ignore */ break;

对于除 HFS+ 之外的大多数文件系统,该文件将是稀疏的。

结论

没有纯 Java 解决方案可以回答“文件系统是否支持稀疏文件”的问题。然而,实际上,只有旧版 MacOS 不支持。

© www.soinside.com 2019 - 2024. All rights reserved.