管理 元数据(文件和文件存储属性)
元数据*的定义是“关于其他数据的数据”。对于文件系统,数据包含在其文件和目录中,元数据跟踪有关以下每个对象的信息:是常规文件,目录还是链接?它的大小,创建日期,最后修改日期,文件所有者,组所有者和访问权限是多少?
文件系统的元数据通常称为文件属性。 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)或通用功能(例如文件所有权)。
支持的视图如下:
-
BasicFileAttributeView –提供所有文件系统实现都必须支持的基本属性的视图。
-
DosFileAttributeView –使用支持 DOS 属性的文件系统上支持的标准四位扩展基本属性视图。
-
PosixFileAttributeView –使用支持 POSIX 系列标准(例如 UNIX)的文件系统上支持的属性扩展基本属性视图。这些属性包括文件所有者,组所有者以及九个相关的访问权限。
-
FileOwnerAttributeView –由任何支持文件所有者概念的文件系统实现支持。
-
AclFileAttributeView –支持读取或更新文件的访问控制列表(ACL)。支持 NFSv4 ACL 模型。也可以支持任何已定义到 NFSv4 模型的 ACL 模型,例如 Windows ACL 模型。
-
UserDefinedFileAttributeView –启用对用户定义的元数据的支持。该视图可以 Map 到系统支持的任何扩展机制。例如,在 Solaris OS 中,您可以使用此视图存储文件的 MIME 类型。
特定的文件系统实现可能仅支持基本文件属性视图,或者可能支持其中一些文件属性视图。文件系统实现可能支持此 API 中未包含的其他属性视图。
在大多数情况下,您不必直接处理任何FileAttributeView
interface。 (如果确实需要直接使用FileAttributeView
,则可以通过getFileAttributeView(Path,Class<V>,LinkOption ...)方法访问它。)
readAttributes
方法使用泛型,可用于读取任何文件属性视图的属性。本页面其余部分的示例使用readAttributes
方法。
本节的其余部分包括以下主题:
基本文件属性
如前所述,要读取文件的基本属性,可以使用Files.readAttributes
方法之一,该方法在一个批量操作中读取所有基本属性。这比分别访问文件系统以读取每个单独的属性要有效得多。 varargs 参数当前支持LinkOption枚举NOFOLLOW_LINKS
。当您不希望跟随符号链接时,请使用此选项。
A word about time stamps:
基本属性集包括三个时间戳:creationTime
,lastModifiedTime
和lastAccessTime
。在特定的实现中可能不支持任何这些时间戳,在这种情况下,相应的访问器方法将返回特定于实现的值。受支持时,时间戳记将作为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 *是 UNIX 便携式 os interface的首字母缩写,并且是一组 IEEE 和 ISO 标准,旨在确保 UNIX 不同版本之间的互操作性。如果程序符合这些 POSIX 标准,则应轻松移植到其他 POSIX 兼容 os。
除了文件所有者和组所有者之外,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 类提供了几种有用的方法,如下所示:
-
上一代码段中使用的
toString
方法将文件许可权转换为字符串(例如rw-r--r--
)。 -
fromString
方法接受表示文件权限的字符串,并构造Set
文件权限。 -
asFileAttribute
方法接受Set
的文件权限,并构造可以传递给Path.createFile
或Path.createDirectory
方法的文件属性。
下面的代码片段从一个文件读取属性并创建一个新文件,将原始文件中的属性分配给新文件:
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示例以类似于chmod
Util 的方式递归更改文件的权限。
设置文件或组所有者
要将名称转换为可以存储为文件所有者或组所有者的对象,可以使用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方法来获取文件系统的所有文件存储。