管理 元数据(文件和文件存储属性)

元数据*的定义是“关于其他数据的数据”。对于文件系统,数据包含在其文件和目录中,元数据跟踪有关以下每个对象的信息:是常规文件,目录还是链接?它的大小,创建日期,最后修改日期,文件所有者,组所有者和访问权限是多少?

文件系统的元数据通常称为文件属性Files类包括可用于获取文件的单个属性或设置属性的方法。

Methods Comment
size(Path) 返回指定文件的大小(以字节为单位)。
isDirectory(Path, LinkOption) 如果指定的Path找到目录文件,则返回 true。
isRegularFile(Path, LinkOption...) 如果指定的Path定位为常规文件,则返回 true。
isSymbolicLink(Path) 如果指定的Path找到了符号链接文件,则返回 true。
isHidden(Path) 如果指定的Path找到文件系统认为隐藏的文件,则返回 true。
getLastModifiedTime(Path, LinkOption...)

setLastModifiedTime(Path, FileTime)
返回或设置指定文件的上次修改时间。
getOwner(Path, LinkOption...)
setOwner(Path, UserPrincipal)
返回或设置文件的所有者。
getPosixFilePermissions(Path, LinkOption...)
setPosixFilePermissions(Path, Set<PosixFilePermission>)
返回或设置文件的 POSIX 文件权限。
getAttribute(Path,String,LinkOption ...)
setAttribute(路径,字符串,对象,LinkOption ...)
返回或设置文件属性的值。

如果程序大约在同一时间需要多个文件属性,则使用检索单个属性的方法可能效率低下。反复访问文件系统以检索单个属性可能会对性能产生不利影响。因此,Files类提供了两个readAttributes方法,以一种批量操作的方式获取文件的属性。

Method Comment
readAttributes(Path,String,LinkOption ...) 读取文件的属性作为批量操作。 String参数标识要读取的属性。
readAttributes(Path,Class<A>,LinkOption ...) 读取文件的属性作为批量操作。 Class<A>参数是请求的属性的类型,该方法返回该类的对象。

在显示readAttributes方法的示例之前,应该提到的是,不同的文件系统对应跟踪哪些属性具有不同的概念。因此,相关的文件属性被分组到视图中。 * view *Map 到特定的文件系统实现(例如 POSIX 或 DOS)或通用功能(例如文件所有权)。

支持的视图如下:

特定的文件系统实现可能仅支持基本文件属性视图,或者可能支持其中一些文件属性视图。文件系统实现可能支持此 API 中未包含的其他属性视图。

在大多数情况下,您不必直接处理任何FileAttributeViewinterface。 (如果确实需要直接使用FileAttributeView,则可以通过getFileAttributeView(Path,Class<V>,LinkOption ...)方法访问它。)

readAttributes方法使用泛型,可用于读取任何文件属性视图的属性。本页面其余部分的示例使用readAttributes方法。

本节的其余部分包括以下主题:

基本文件属性

如前所述,要读取文件的基本属性,可以使用Files.readAttributes方法之一,该方法在一个批量操作中读取所有基本属性。这比分别访问文件系统以读取每个单独的属性要有效得多。 varargs 参数当前支持LinkOption枚举NOFOLLOW_LINKS。当您不希望跟随符号链接时,请使用此选项。

A word about time stamps:

基本属性集包括三个时间戳:creationTimelastModifiedTimelastAccessTime。在特定的实现中可能不支持任何这些时间戳,在这种情况下,相应的访问器方法将返回特定于实现的值。受支持时,时间戳记将作为FileTime对象返回。

以下代码段读取并打印给定文件的基本文件属性,并使用BasicFileAttributes类中的方法。

Path file = ...;
BasicFileAttributes attr = Files.readAttributes(file, BasicFileAttributes.class);

System.out.println("creationTime: " + attr.creationTime());
System.out.println("lastAccessTime: " + attr.lastAccessTime());
System.out.println("lastModifiedTime: " + attr.lastModifiedTime());

System.out.println("isDirectory: " + attr.isDirectory());
System.out.println("isOther: " + attr.isOther());
System.out.println("isRegularFile: " + attr.isRegularFile());
System.out.println("isSymbolicLink: " + attr.isSymbolicLink());
System.out.println("size: " + attr.size());

除了本示例中显示的访问器方法外,还有一个fileKey方法返回唯一标识文件的对象,或者返回null(如果没有可用的文件密钥)。

设置时间戳

以下代码段以毫秒为单位设置上次修改时间:

Path file = ...;
BasicFileAttributes attr =
    Files.readAttributes(file, BasicFileAttributes.class);
long currentTime = System.currentTimeMillis();
FileTime ft = FileTime.fromMillis(currentTime);
Files.setLastModifiedTime(file, ft);
}

DOS 文件属性

在 DOS 以外的文件系统(例如 Samba)上也支持 DOS 文件属性。以下代码段使用DosFileAttributes类的方法。

Path file = ...;
try {
    DosFileAttributes attr =
        Files.readAttributes(file, DosFileAttributes.class);
    System.out.println("isReadOnly is " + attr.isReadOnly());
    System.out.println("isHidden is " + attr.isHidden());
    System.out.println("isArchive is " + attr.isArchive());
    System.out.println("isSystem is " + attr.isSystem());
} catch (UnsupportedOperationException x) {
    System.err.println("DOS file" +
        " attributes not supported:" + x);
}

但是,可以使用setAttribute(路径,字符串,对象,LinkOption ...)方法设置 DOS 属性,如下所示:

Path file = ...;
Files.setAttribute(file, "dos:hidden", true);

POSIX 文件权限

除了文件所有者和组所有者之外,POSIX 还支持九种文件权限:文件所有者,同一组成员和“其他任何人”的读,写和执行权限。

以下代码片段读取给定文件的 POSIX 文件属性,并将它们打印到标准输出。该代码使用PosixFileAttributes类中的方法。

Path file = ...;
PosixFileAttributes attr =
    Files.readAttributes(file, PosixFileAttributes.class);
System.out.format("%s %s %s%n",
    attr.owner().getName(),
    attr.group().getName(),
    PosixFilePermissions.toString(attr.permissions()));

PosixFilePermissions helper 类提供了几种有用的方法,如下所示:

下面的代码片段从一个文件读取属性并创建一个新文件,将原始文件中的属性分配给新文件:

Path sourceFile = ...;
Path newFile = ...;
PosixFileAttributes attrs =
    Files.readAttributes(sourceFile, PosixFileAttributes.class);
FileAttribute<Set<PosixFilePermission>> attr =
    PosixFilePermissions.asFileAttribute(attrs.permissions());
Files.createFile(file, attr);

asFileAttribute方法将权限包装为FileAttribute。然后,代码try使用这些权限创建一个新文件。请注意,umask也适用,因此新文件可能比所请求的权限更安全。

要将文件的权限设置为以硬编码字符串 表示的值,可以使用以下代码:

Path file = ...;
Set<PosixFilePermission> perms =
    PosixFilePermissions.fromString("rw-------");
FileAttribute<Set<PosixFilePermission>> attr =
    PosixFilePermissions.asFileAttribute(perms);
Files.setPosixFilePermissions(file, perms);

Chmod示例以类似于chmodUtil 的方式递归更改文件的权限。

设置文件或组所有者

要将名称转换为可以存储为文件所有者或组所有者的对象,可以使用UserPrincipalLookupService服务。此服务将名称或组名称查找为字符串,并返回代表该字符串 的UserPrincipal对象。您可以使用FileSystem.getUserPrincipalLookupService方法获得默认文件系统的用户主体查找服务。

以下代码段显示了如何使用setOwner方法设置文件所有者:

Path file = ...;
UserPrincipal owner = file.GetFileSystem().getUserPrincipalLookupService()
        .lookupPrincipalByName("sally");
Files.setOwner(file, owner);

Files类中没有用于设置组所有者的专用方法。但是,直接执行此操作的安全方法是通过 POSIX 文件属性视图,如下所示:

Path file = ...;
GroupPrincipal group =
    file.getFileSystem().getUserPrincipalLookupService()
        .lookupPrincipalByGroupName("green");
Files.getFileAttributeView(file, PosixFileAttributeView.class)
     .setGroup(group);

用户定义的文件属性

如果文件系统实现支持的文件属性不足以满足您的需要,则可以使用UserDefinedAttributeView来创建和跟踪自己的文件属性。

一些实现将此概念 Map 到诸如 NTFS 备用数据流之类的功能,以及诸如 ext3 和 ZFS 之类的文件系统上的扩展属性。大多数实现对值的大小施加了限制,例如,ext3 将大小限制为 4 KB。

可以使用以下代码片段将文件的 MIME 类型存储为用户定义的属性:

Path file = ...;
UserDefinedFileAttributeView view = Files
    .getFileAttributeView(file, UserDefinedFileAttributeView.class);
view.write("user.mimetype",
           Charset.defaultCharset().encode("text/html");

要读取 MIME type 属性,可以使用以下代码片段:

Path file = ...;
UserDefinedFileAttributeView view = Files
.getFileAttributeView(file,UserDefinedFileAttributeView.class);
String name = "user.mimetype";
ByteBuffer buf = ByteBuffer.allocate(view.size(name));
view.read(name, buf);
buf.flip();
String value = Charset.defaultCharset().decode(buf).toString();

Xdd示例显示了如何获取,设置和删除用户定义的属性。

Note:

在 Linux 中,可能必须启用扩展属性才能使用户定义的属性起作用。如果在try访问用户定义的属性视图时收到UnsupportedOperationException,则需要重新挂载文件系统。以下命令使用 ext3 文件系统的扩展属性重新挂载根分区。如果此命令不适用于您的 Linux,请查阅文档。

$ sudo mount -o remount,user_xattr /

如果要永久保留更改,请在/etc/fstab中添加一个条目。

文件存储属性

您可以使用FileStore类来学习有关文件存储的信息,例如可用空间。 getFileStore(Path)方法获取指定文件的文件存储。

以下代码段显示了特定文件所在的文件存储的空间使用情况:

Path file = ...;
FileStore store = Files.getFileStore(file);

long total = store.getTotalSpace() / 1024;
long used = (store.getTotalSpace() -
             store.getUnallocatedSpace()) / 1024;
long avail = store.getUsableSpace() / 1024;

DiskUsage示例使用此 API 打印默认文件系统中所有存储的磁盘空间信息。本示例使用FileSystem类中的getFileStores方法来获取文件系统的所有文件存储。

首页