StandardOpenOption.SPARSE的用途是什么?

fge*_*fge 4 java filesystems file-io java-7

Java 7 定义了该选项,但我仍然无法理解它的用处。

public static void main(final String... args)
    throws IOException
{
    final long offset = 1L << 31;
    final RandomAccessFile f = new RandomAccessFile("/tmp/foo", "rw");
    f.seek(offset);
    f.writeInt(2);
    f.close();
}
Run Code Online (Sandbox Code Playgroud)

当我查询文件“ shell wise”时,我得到了预期的结果:

$ cd /tmp
$ stat --format %s foo
2147483652
$ du --block-size=1 foo
4096    foo
Run Code Online (Sandbox Code Playgroud)

也就是说,inode真实地声明该文件的大小接近2 GB,但是由于基础fs的块大小为4k,因此其磁盘使用情况实际上是一个块。好。

但是我不需要Java 7 StandardOpenOption.SPARSE。实际上,如果我使用Java 7 JVM运行此完全相同的代码,则结果不会改变。

现在,转到一些仅Java 7的代码:

public static void main(final String... args)
    throws IOException
{
    final ByteBuffer buf = ByteBuffer.allocate(4).putInt(2);
    buf.rewind();

    final OpenOption[] options = {
        StandardOpenOption.WRITE,
        StandardOpenOption.CREATE_NEW
    };
    final Path path = Paths.get("/tmp/foo");
    Files.deleteIfExists(path);

    try (
        final SeekableByteChannel channel
            = Files.newByteChannel(path, options);
    ) {
        channel.position(1L << 31);
        channel.write(buf);
    }
}
Run Code Online (Sandbox Code Playgroud)

还会创建一个稀疏文件,而我根本不需要指定StandardOpenOption.SPARSE

那么,它的作用是什么?是否有任何OS /文件系统组合真正影响了该行为?

ysh*_*vit 6

I / O教程中的Oracle注释将NTFS列为该选项重要的一个文件系统。微软有关NTFS中稀疏文件支持的文档指出,稀疏文件必须明确标记为稀疏,并且列出了针对稀疏文件的特定操作(对区域进行清零,使用非零数据搜索范围等)。

我没有方便尝试的Windows框,但是在教程中特别注明了NTFS,这可能是一个集中搜索的地方。