`
AsWater
  • 浏览: 24761 次
  • 性别: Icon_minigender_1
  • 来自: 成都
社区版块
存档分类
最新评论

Java SE 7新特性之文件操作(5) - 管理元数据

阅读更多

转自 开发者的天空


在文件系统中,文件或者目录的元数据是和文件或者目录本身存储在一起的,而且元数据保存了很多的信息,例如:对象 是文件还是目录,抑或是符号链接。文件的大小、创建 时间、最后修改时间、文件的所有者、组、访问权限等。
java.nio.file.attribute包提供了访问和管理文件系统元数据(通常叫做文件属性)的功能。不同的文件系统提供的文件属性是不一样 的,所以我们按照这个将文件的属性划分成了不同的视图(View)。每个View对应一个文件系统的实现,如POSIX(Unix使用的文件系统)或 DOS;或者是所有文件系统共有的属性,如文件的所有权。当我们读取文件的属性的时候,是一次读取整个视图的属性的。Java 所支持的视图有:
BasicFileAttributeView – 所有的文件系统实现都必须提供的属性的视图。
DosFileAttributeView – 扩展了BasicFileAttributeView,添加了DOS文件系统能够支持的几种属性。
PosixFileAttributeView – 扩展了BasicFileAttributeView,添加了POSIX文件系统能够支持的几种属性。
FileOwnerAttributeView – 任何文件系统实现都会支持文件所有者的属性。这个View就包含这个属性。
AclFileAttributeView – 支持读取和更新文件的访问控制列表。支持NFSv4访问控制列表模型。所有定义了到NFSv4的映射的访问控制列表模型也同样支持,如Windows的访 问控制列表模型。
UserDefinedFileAttributeView – 支持用户自定义的元数据。这个View可以被映射到文件系统提供的扩展机制。例如在Solaris操作系统上,可以将这个View存储MIMEtype。
不同的文件系统可能支持不同的一个或几个view,也有可能含有上面所有的View都没有包含的文件属性。
Attributes类
大多数情况下,我们不需要直接使用FileAttributeView接口,Attributes类提供了转换的方法来读取和设置文件属性。
下面是Attributes类提供的一些方法:
读取或设置基本的文件属性:
readBasicFileAttributes(FileRef, LinkOption...)
setLastAccessTime(FileRef, FileTime)
setLastModifiedTime(FileRef, FileTime)

读取或设置POSIX文件属性
readPosixFileAttributes(FileRef, LinkOption...)
setPosixFilePermissions(FileRef, Set<PosixFilePermission>)

读取或设置文件的所有者
getOwner(FileRef)
setOwner(FileRef, UserPrincipal)

一次读取所有的文件属性
readAttributes(FileRef, String, LinkOption...)

读取或设定特定的文件属性
getAttribute(FileRef, String, LinkOption...)
setAttribute(FileRef, String, Object)

读取DOS文件属性
readDosFileAttributes(FileRef, LinkOption...)

读取或设置文件的访问控制列表。
getAcl(FileRef)
setAcl(FileRef, List<AclEntry>)

读取文件存储空间的属性,如总空间、有效空间、未分配空间等。
readFileStoreSpaceAttributes(FileStore)

每个read方法都返回一个对象,该对象会提供访问方法,我们通过这些访问方法能够很方便的获得特定的文件属性的值。
要想读取基本的文件信息,那么可以调用readBasicFileAttributes(FileRef, LinkOption...)方法。这个方法支持的LinkOption就只有NOFOLLOW_LINKS。这个方法会一次性的读取所有的基本的文件属 性并返回一个BasicFileAttributes对象,我们可以访问该对象获取具体的文件属性。如果程序对文件没有访问权限,该方法会抛出 SecurityException异常。要注意的是,并不是所有文件系统的实现都支持创建时间、最后修改时间和最后访问时间这三个属性。如果某个属性不 被支持,则调用该属性的get方法时会返回null。下面就是一个读取文件的基本属性的例子:

Path file = ...;
BasicFileAttributes attr = Attributes.readBasicFileAttributes(file);

if (attr.creationTime() != null) {
    System.out.println("creationTime: " + attr.creationTime());
}
if (attr.lastAccessTime() != null) {
    System.out.println("lastAccessTime: " + attr.lastAccessTime());
}
if (attr.lastModifiedTime() != null) {
    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());

 下面的例子中,我们检查了对一个文件的访问权限,判断该文件是常规的文件还是目录:

import static java.nio.file.AccessMode.*;

Path file = ...;
boolean error=false;

try {
    file.checkAccess(READ, EXECUTE);
    if (!Attributes.readBasicFileAttributes(file).isRegularFile()) {
        error = true;
    }
} catch (IOException x) {
    //Logic for error condition...
    error = true;
}
if (error) {
    //Logic for failure...
    return;
}
//Logic for executable file...

 设置时间戳

前面的文件基本属性的代码中演示了怎样获取文件的时间戳,Attributes类还提供了两个方法来设置时间戳:setLastAccessTime和 setLastModifiedTime,下面是这两个方法的示例:

Path file = ...;
BasicFileAttributes attr = Attributes.readBasicFileAttributes(file);
long currentTime = System.currentTimeMillis();
if (attr.lastModifiedTime() != null) {
    FileTime ft = FileTime.fromMillis(currentTime);
    Attributes.setLastModifiedTime(file, ft);
} else {
    System.err.println("lastModifiedTime time stamp not supported");
}

 

DOS的文件属性
要获取一个文件的DOS的文件属性,需要调用readDosFileAttributes方法。这个方法会返回一个DosFileAttributes对 象,该对象提供了获取DOS文件属性的方法,例如:

Path file = ...;
try {
    DosFileAttributes attr = Attributes.readDosFileAttributes(file);
    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 (IOException x) {
    System.err.println("DOS file attributes not supported:" + x);
}

 我们可以使用setAttribute方法来设置DOS文件属性,如:

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

 要注意的是,不是只有DOS操作系统才支持DOS文件属性,有些操作系统如Samba也支持DOS文件属性。
POSIX的文件属性
POSIX是Portable Operation System Interface for UNIX的缩写,而且IEEE和ISO定义很多标准来保证不同的UNIX之间的户操作性,因此对于开发人员来说,针对POSIX编写的程序能够很容易的运 行在不同的兼容POSIX的文件系统上。
要读取POSIX文件属性,需要调用readPosixFileAttributes方法。除了文件所有者和所属组,POSIX还支持9种文件权限许可组 合:读、写、执行三种权限和文件所有者、同组的用户和其他用户三种角色的组合(3 × 3 = 9)。下面就是读取POSIX文件属性的简单的例子:

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

 下面的代码读取了一个文件的属性,然后创建了一个新的文件,将原有的文件的权限属性赋予新创建的文件:

Path sourceFile = ...;
Path newFile = ...;
PosixFileAttributes attrs = Attributes.readPosixFileAttributes(sourceFile);
FileAttribute<Set<PosixFilePermission>> attr =
          PosixFilePermissions.asFileAttribute(attrs.permissions());
try {
    file.createFile(attr);
} catch (IOException x) {
    //unable to create the file
}

 上面的代码中我们使用了PosixFilePermission类,该类是一个帮助类,提供了一些方法来读取和生成文件权限,这里就不详细解释了。
如果想指定创建的文件的权限,可以使用下面的代码:

Path file = ...;
Set<PosixFilePermission> perms = PosixFilePermissions.fromString("rw-------");
FileAttribute<Set<PosixFilePermission>> attr = PosixFilePermissions.asFileAttribute(perms);
try {
    Attributes.setPosixFilePermissions(file, perms);
} catch (IOException x) {
    System.err.println(x);
}

 文件有所有者的属性和所属组的属性,在设置这些属性的时候,我们需要传入一个UserPrincipal对象作为参数,我们可以使用 UserPrincipalLookupService来根据用户名或组名来创建该对象。UserPrincipalLookupService实例可以 通过FileSystem.getUserPrincipalLookupService方法获得。下面就是设置所有者属性的例子:

Path file = ...;
try {
    UserPrincipal owner = file.GetFileSystem().getUserPrincipalLookupService()
                          .lookupPrincipalByName("sally");
    Attributes.setOwner(file, owner);
} catch (IOException x) {
    System.err.println(x);
}

 Attributes类没有提供设置所属组的方法,如果要设置所属组,需要调用POSIX文件属性视图来进行,下面是示例代码:

Path file = ...;
try {
    GroupPrincipal group = file.getFileSystem().getUserPrincipalLookupService()
                          .lookupPrincipalByGroupName("green");
    file.getFileAttributeView(PosixFileAttributeView.class).setGroup(group);
} catch (IOException x) {
    System.err.println(x);
}

 用户定义的文件属性
如果文件系统支持的属性对你来说还不够用,你可以通过UserDefinedAttributeView来创建和跟踪自己的文件属性。
下面的例子中,我们将MIME类型作为一个用户自定义的属性:

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

 要读取MIME类型属性,要使用以下的代码:

Path file = ...;
UserDefinedFileAttributeView view = file
    .getFileAttributeView(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();

 如果文件系统不支持扩展属性,那么会抛出一个UnsupportedOperationException异常,你可以咨询系统管理员来确认系统是否支持 文件的扩展属性并进行相应的配置。

文件存储属性
文件存储属性其实我们应该非常熟悉的属性,我们查看硬盘属性的时候,经常看到硬盘总的存储空间,使用了的存储空间,空闲的存储空间等就是文件存储属性。下 面是获取文件存储属性的代码:

Path file = ...;
FileStore store = file.getFileStore();
FileStoreSpaceAttributes attr = Attributes.readFileStoreSpaceAttributes(store);

System.out.println("total: " + attr.totalSpace() );
System.out.println("used:  " + (attr.totalSpace() - attr.unallocatedSpace()) );
System.out.println("avail: " + attr.usableSpace() );
 
分享到:
评论

相关推荐

    Java SE 6 新特性

    5. **JDBC 4.0**:Java Database Connectivity (JDBC) API在Java 6中升级到4.0版本,添加了自动连接管理、自动类型映射和获取数据库元数据的新方法,使得数据库操作更加方便。 6. **改进的泛型**:泛型的实现得到了...

    java虚拟机规范 Java SE7

    每个类文件包含元数据、方法和字段定义。了解类文件格式有助于理解JVM如何加载和执行字节码。 2. **字节码指令集**:JVM使用一套简单的指令集来执行程序。这些指令包括数据操作、控制流、对象创建和方法调用等。...

    Java SE 7 Documentation

    Java SE 7(Java Standard Edition 7)是Java编程语言的一个重要版本,它引入了许多新特性和改进,为开发者提供了更高效、更安全的开发环境。这个文档集合是Oracle公司发布的JDK 1.7(也称为Java Development Kit 7...

    Java虚拟机规范(Java SE 7)-完整目录书签文字版

    Java SE 7(Java Standard Edition 7)是Java发展的一个重要版本,引入了许多新特性和改进,使得开发者能够编写更高效、更可靠的代码。在《Java虚拟机规范(Java SE 7)》中,详细阐述了JVM的工作原理、内存模型、类...

    java se6 全方位学习 ---源代码及附录

    10. **注解(Annotations)**:注解在Java 6中被广泛使用,用于元数据的声明,可以用于编译器检查、代码生成、运行时处理等场景。 这个压缩包中的“javase6全方位学习”很可能包含了一系列的示例代码、教程文档和...

    Java虚拟机规范(Java SE 7)中文版

    Java SE 7(Java Standard Edition 7)是Java平台的一个重要版本,引入了许多新特性和改进,使得开发和运行Java应用程序更加高效。本篇主要基于《Java虚拟机规范(Java SE 7)中文版》进行详细的解读。 1. **类加载...

    Java Virtual Machine Specification Java SE 7 中文版

    10. 文件I/O改进:Java SE 7引入了NIO.2,提供了一组新的文件I/O API,增加了对路径、文件系统、异步I/O操作的支持,提高了文件操作的效率和易用性。 总的来说,Java Virtual Machine Specification Java SE 7 中文...

    The Java® Virtual Machine Specification Java SE 12 Edition.rar

    《Java® Virtual Machine Specification Java SE 12 Edition》是官方发布的关于JVM在Java SE 12版本中的详细规范,旨在定义JVM如何执行字节码、管理内存以及实现各种平台无关的特性。 1. **JVM概述**: - JVM是...

    Java SE6 技术手册(下)

    总的来说,《Java SE6 技术手册(下)》是Java开发者必备的参考书籍之一,它不仅涵盖了Java SE6的关键特性,还提供了丰富的实践案例和技巧,帮助读者提升开发效率,掌握Java平台的核心技术。无论你是初学者还是经验...

    JAVA SE6.0编程指南源码

    4. **NIO.2**:Java SE 6引入了NIO.2,提供了一组新的API来处理文件系统操作,包括异步I/O和文件路径操作,这在处理大量文件时效率更高。 5. **Swing增强**:Java 6对Swing GUI库进行了一些改进,比如JDBC结果集的...

    java se学习教程

    注解(Annotation)是元数据的一种形式,可以为编译器和JVM提供额外的信息,如用于代码自动生成、运行时检查等。 九、泛型 Java泛型引入了类型参数,提高了代码的安全性和重用性。泛型可以应用于类、接口和方法,...

    java-SE基础学习资料及介绍

    7. **I/O流**:学习输入输出流,包括字节流和字符流,以及文件操作和网络通信。 8. **反射**:理解反射机制,如何在运行时动态获取类的信息并调用方法。 9. **泛型**:学习泛型的使用,如何限制集合中存储的数据...

    java se全程学习案例

    7. **反射**:反射机制允许程序在运行时动态获取类的信息并操作类的对象,是Java强大的特性之一。 8. **泛型**:泛型引入了类型参数,增强了代码的类型安全性和重用性,如ArrayList、HashMap, V&gt;等。 9. **枚举与...

    Java虚拟机规范(Java SE 7).7z

    Java SE 7(Java Standard Edition 7)是Java平台的一个重要版本,包含了对JVM的重大改进和新特性。本篇文章将深入探讨Java虚拟机在Java SE 7中的核心概念、改进和相关知识点。 一、JVM架构 JVM由以下几个关键组件...

    java SE最经典的桌面小程序(N多demo)适合初学者

    2. **面向对象编程**:Java的核心特性之一是面向对象,包括类、对象、继承、封装和多态等概念。初学者可以通过DEMO学习如何创建和使用类,理解类与对象的关系,以及如何通过继承和多态实现代码复用和扩展。 3. **...

    Java语言规范 SE 7 版本-带书签文字版.zip

    7. **NIO.2**:新的I/O API,提供了一种更高效、非阻塞的数据输入/输出方式,包括文件系统操作、异步通道组、文件属性修改等。 8. **枚举与注解**:Java SE 7对枚举和注解的用法进行了详细规定,枚举可以有方法和...

    JAVA SE API HELP

    10. **注解**:注解是一种元数据,可以用于给代码添加信息,编译器或运行时系统可以使用这些信息。例如,`@Override`确保方法是重写父类方法,`@Deprecated`标记过时的方法。 "JAVA SE API HELP TEXT"文档详细阐述...

    Java SE 复习资料

    9. **泛型**:泛型是Java 5引入的新特性,用于增强类型安全,减少类型转换,并允许编译器进行更严格的检查。理解和运用泛型,可以编写出更清晰、更安全的代码。 10. **枚举与注解**:枚举提供了一种安全的方式来...

    Java SE 类库查询手册

    集合框架是Java SE中最基础也是最核心的部分之一,它提供了一组接口(如List、Set、Queue)和实现这些接口的类(如ArrayList、HashSet、LinkedList等),以及对它们进行操作的工具类(如Collections和Comparator)。...

    Java SE Tutorial 2022-03-04

    5. **IO流**:Java的IO流系统允许程序进行输入输出操作,包括文件操作、网络通信等。掌握InputStream、OutputStream、Reader、Writer以及NIO(New IO)框架对于处理数据交换至关重要。 6. **多线程**:Java提供内置...

Global site tag (gtag.js) - Google Analytics