首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >java.nio.file.Files的哪些方法遵循符号链接,哪些不遵循符号链接?

java.nio.file.Files的哪些方法遵循符号链接,哪些不遵循符号链接?
EN

Stack Overflow用户
提问于 2019-04-29 05:37:45
回答 1查看 800关注 0票数 3

Java helper类java.nio.file.Files具有访问文件属性的方法。一些类方法遵循符号链接(所有带有LinkOption参数的方法),而对于其他一些方法,则不清楚是否遵循符号链接(没有LinkOption参数的方法)。

以下是一些遵循符号链接的方法:

  • Files.isDirectory(Path, LinkOption...)
  • Files.isRegular(Path, LinkOption...)
  • Files.getAttribute(Path, String, LinkOption...)
  • Files.getLastModified(Path, LinkOption...)
  • Files.getOwner(Path, LinkOption...)
  • Files.getPosixFilePermission(Path, LinkOption...)

对于其他一些方法,很难确定它们是否遵循符号链接(没有LinkOption...参数,在javadoc中也没有提到符号链接):

  • Files.isSymbolicLink(Path)
  • Files.isExecutable(Path)
  • Files.isReadable(Path)
  • Files.isWritable(Path)
  • Files.isHidden(Path)
  • Files.size(Path)
  • Files.getFileStore(Path)

跟随符号链接的不带LinkOption...参数的方法有哪些?为什么?

EN

回答 1

Stack Overflow用户

发布于 2019-04-29 05:37:45

TLDR:在大多数情况下,这似乎是一个FileSystemProvider实现选择是否遵循符号链接(这可能回答了“为什么”的问题)。符号链接包括:

如下所示:

  • Files.size(Path)

主要关注的是:

  • Files.getFileStore(Path):在Windows和Linux上遵循,在Jimfs

上不遵循。

未遵循:

  • Files.isSymbolic(Path)

大多数情况下没有遵循:

  • Files.isExecutable(Path):在Windows和Unix上不遵循,但在Jimfs
  • Files.isReadable(Path)上遵循:在Windows和Unix上不遵循,但在Jimfs

上遵循

完全特定于实现:

  • Files.isWritable(Path):在Windows上跟随但不在Unix
  • Files.isHidden(Path)上跟随:在Windows上跟随但在Unix

上不跟随

您可以通过调用Files.readAttributes(Path, Class, LinkOption...)并使用返回的属性来确定是否遵循符号链接。

Files.isSymbolic(Path)不遵循符号链接

对于Files.isSymbolic(Path),原因很明显:如果该方法默认遵循符号链接,它将始终返回false

Files.isHidden(Path)在Windows上遵循符号链接,但在Unix上不遵循。

从方法签名中,我们可能认为该方法不遵循符号链接(因为没有LinkOption...参数)。然而,这并不是那么明显。

委托给java.nio.file.spi.FileSystemProvider.isHidden(Path)和javadoc实现的Files.isHidden(Path)方法没有指定该方法是否遵循符号链接。

在Windows上,它是implemented by following symbolic links,请参见第465行( WindowsFileAttributes.get(file, true)调用中的true参数告诉您遵循符号链接):

代码语言:javascript
复制
@Override
public boolean isHidden(Path obj) throws IOException { 
    WindowsPath file = WindowsPath.toWindowsPath(obj); 
    file.checkRead(); 
    WindowsFileAttributes attrs = null; 
    try { 
        attrs = WindowsFileAttributes.get(file, true); 
    } catch (WindowsException x) { 
        x.rethrowAsIOException(file); 
    } 
    // DOS hidden attribute not meaningful when set on directories 
    if (attrs.isDirectory()) 
        return false; 
    return attrs.isHidden(); 
} 

在Unix上,这个方法是implemented without following symbolic links (它只检查文件是否以“.”开头):

代码语言:javascript
复制
@Override
public boolean isHidden(Path obj) {
    UnixPath file = UnixPath.toUnixPath(obj);
    file.checkRead();
    UnixPath name = file.getFileName();
    if (name == null)
        return false;
    return (name.asByteArray()[0] == '.');
}

因此,我们可以得出结论,这是特定于实现的。

在大多数文件系统中,Files.isExecutable(Path)不遵循符号链接

此方法委托给Files.isAccessible(Path, AccessMode.EXECUTE),后者又委托给FileSystemProvider.checkAccess(Path, AccessMode...)方法。

在Windows上,WindowsFileSystemProvider.checkAccess(Path, AccessMode...)方法委托给java.lang.SecurityManager来决定文件是否可执行。SecurityManager不遵循符号链接,所以我们可以假设Files.isExecutable(Path)在Windows上不遵循符号链接。

在Unix上,UnixFileSystemProvider.checkAccess(Path, AccessMode...)方法也委托给SecurityManager,我们可以假设Files.isExecutable(Path)在Unix上也不遵循符号链接。

在Jimfs (来自谷歌的内存文件系统)上,调用委托给遵循符号链接的com.google.common.jimfs.FileSystemView.checkAccess(JimfsPath) (即使Jimfs不支持访问控制):

代码语言:javascript
复制
public void checkAccess(JimfsPath path) throws IOException {
    // just check that the file exists
    lookUpWithLock(path, Options.FOLLOW_LINKS).requireExists(path);
}

因此,我们可以得出结论,根据文件系统的不同,Files.isExecutable(Path)可能会遵循符号链接,但在大多数情况下(Unix+Windows)不会。

在大多数文件系统上,Files.isReadable(Path)不遵循符号链接

Files.isReadable(Path)的实现与isExecutable(Path)非常相似:在Unix和Windows上不使用链接,在Jimfs上使用链接。

Files.isWritable(Path)

对于Files.isExecutable(Path)isWritable(Path)方法委托给FileSystemProvider.checkAccess(Path)

在Windows上,这需要确定文件是否具有只读属性,这是通过以下链接完成的(请参阅上面的WindowsFileSystemProvider代码)。

在Unix上,这显然是在没有遵循符号链接的情况下完成的(参见上面的UnixFileSystemProvider )。

因此,我们可以得出结论,这是特定于实现的。

Files.size(Path)跟随符号链接

该实现委托给readAttributes,因此它遵循所有文件系统实现的符号链接:

代码语言:javascript
复制
public static long size(Path path) throws IOException {
    return readAttributes(path, BasicFileAttributes.class).size();
}

Files.getFileStore(Path)

该方法委托给FileSystemProvider.getFileStore(Path)方法。

在Windows上,它使用跟随符号链接的WindowsFileStore.create(Path) (参见true参数):

代码语言:javascript
复制
static WindowsFileStore create(WindowsPath file) throws IOException {
    try {
        // if the file is a link then GetVolumePathName returns the
        // volume that the link is on so we need to call it with the
        // final target
        String target = WindowsLinkSupport.getFinalPath(file, true);
  ...

在Unix上,FileSystemProvider.getFileStore(Path)方法是抽象的,由子类实现,例如[LinuxFileSystem][3]

代码语言:javascript
复制
@Override
LinuxFileStore getFileStore(UnixPath path) throws IOException {
    return new LinuxFileStore(path);

}

这个类通过获取带有以下链接的属性来构造UnixFileStore ( UnixFileAttributes.get()调用中的true参数):

代码语言:javascript
复制
private static long devFor(UnixPath file) throws IOException {
    try {
        return UnixFileAttributes.get(file, true).dev();
    } catch (UnixException x) {
        x.rethrowAsIOException(file);
        return 0L;  // keep compiler happy
    }
}

在Jimfs中,FileStore似乎是在创建时附加到文件的,因此,看起来没有遵循链接。

因此,我们可以得出结论,在大多数文件系统实现中,Files.getFileStore(Path)都使用符号链接。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55894781

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档