Java 7 中 NIO.2 的使用——第二节 元数据文件的属性

  如果你有很多疑问关于一个文件或目录,它是否是隐藏的,它的大小是多少,谁拥有它,你可以从元数据中得到这些信息。所谓的元数据,就是描述数据的数据。

  NIO.2组织了这些原数据的属性的概念,并提供了java.nio.file.attribute 包去访问它们。因为不同的文件系统有不同的概念跟踪这些属性,所以,NIO.2根据特定的文件系统进行映射然后对应到不同的view中。通常情况下,view会提供一些通用的方法,例如readAttributes()。除此而外,你可以通过getAttribute()setAttribute() 方法来提取或设置单一的属性,这些方法在 java.nio.file.Files 类中都是可用的。依据view,其他的方法可以完成额外的任务。

  在NIO.2 中支持六种view,下面就是这些view的概述。

  • BasicFileAttributeView:这是最基本的属性并且被所有的文件系统所支持。这个属性视图的名字叫做basic。
  • DosFileAttributeView:Windows操作系统中的文件系统一般使用遗留的“DOS”文件属性视图,该视图包含的属性有是否为只读文件(readonly)、是否为隐藏文件(hidden)、是否为系统文件(system)和是否为归档文件(archive)等。DosFileAttributeView接口中包含了设置这些属性的方法。
  • PosixFileAttributeView:这个视图是基本属性视图的扩展,用来支持可移植操作系统的Unix。
  • FileOwnerAttributeView:这个视图支持包含文件所有者之一概念的文件系统的实现。
  • AclFileAttributeView:这个视图支持读取和更新文件的ACL(access control list)操作。
  • UserDefinedFileAttributeView:这个视图支持用户自定义的元数据。

  --------------------------------------------------------------------------------------------------------------------------------

  确定视图支持一个特定的文件系统

  在你尝试访问view的属性时,请确认你的文件系统是否支持对应的view。NIO.2可以让你根据名字或是检查文件的存储(FileStore类描述了任何存储类型的映射,例如分区,设备,卷,等等)来列出所有支持的视图列表。

  一旦获取了默认系统的访问权限,通过调用 FileSystems.getDefault()方法,你就会很容易的遍历所有的支持的view通过调用 FileSystem.supportedFileAttributeViews()方法。请看下面的代码。

import java.nio.file.FileSystem;
import java.nio.file.FileSystems;
import java.util.Set;
…
FileSystem fs = FileSystems.getDefault();
Set<String> views = fs.supportedFileAttributeViews();

for (String view : views) {
      System.out.println(view);
}

  在Windows7下执行的结果:

  owner
  dos
  acl
  basic
  user

  你可以通过调用FileStore.supportsFileAttributeView() 方法来测试特定的文件存储上的view,你可以传递view描述的字符串,或是直接传递view的接口名字。下面演示在支持的文件存储上检查是否支持basic视图的代码。

import java.nio.file.FileStore;
import java.nio.file.FileSystem;
import java.nio.file.FileSystems;
import java.nio.file.attribute.BasicFileAttributeView;
…
FileSystem fs = FileSystems.getDefault();
for (FileStore store : fs.getFileStores()) {
   boolean supported = store.supportsFileAttributeView(BasicFileAttributeView.class);
    System.out.println(store.name() + " ---" + supported);
}

  当然,你也可以测试一个特定的文件支持的view。

import java.io.IOException;
 import java.nio.file.FileStore;
 import java.nio.file.Files;
 import java.nio.file.Path;
 import java.nio.file.Paths;
 …
 Path path = Paths.get("C:/rafaelnadal/tournaments/2009", "BNP.txt");

try {
     FileStore store = Files.getFileStore(path);
     boolean supported = store.supportsFileAttributeView("basic");
     System.out.println(store.name() + " ---" + supported);
 } catch (IOException e) {
     System.err.println(e);
 }

  --------------------------------------------------------------------------------------------------------------------------------

  Basic 视图

  大部分文件系统的实现支持一些通用的属性,例如大小,创建时间,上次访问时间,最后修改时间等等。这些属性被分组放在BasicFileAttributeView中,可以提取或设置下面描述的部分中。

  使用readAttributes()方法获得成批的属性

  你可以通过使用readAttributes()方法获取成批的属性,这个方法的参数支持 LinkOption.NOFOLLOW_LINKS 枚举类型,意思是不包含符号链接的文件。

 import java.io.IOException;
 import java.nio.file.Files;
 import java.nio.file.Path;
 import java.nio.file.Paths;
 import java.nio.file.attribute.BasicFileAttributes;
 …
 BasicFileAttributes attr = null;
 Path path = Paths.get("C:/rafaelnadal/tournaments/2009", "BNP.txt");

try {
     attr = Files.readAttributes(path, BasicFileAttributes.class);
 } catch (IOException e) {
     System.err.println(e);
 }

System.out.println("File size: " + attr.size());
 System.out.println("File creation time: " + attr.creationTime());
 System.out.println("File was last accessed at: " + attr.lastAccessTime());
 System.out.println("File was last modified at: " + attr.lastModifiedTime());

System.out.println("Is directory? " + attr.isDirectory());
 System.out.println("Is regular file? " + attr.isRegularFile());
 System.out.println("Is symbolic link? " + attr.isSymbolicLink());
 System.out.println("Is other? " + attr.isOther());

  通过getAttribute()方法获得单一属性。

import java.io.IOException;
 import java.nio.file.Files;
 import java.nio.file.Path;
 import java.nio.file.Paths;
 import static java.nio.file.LinkOption.NOFOLLOW_LINKS;
 …
 Path path = Paths.get("C:/rafaelnadal/tournaments/2009", "BNP.txt");
 try {
     long size = (Long)Files.getAttribute(path, "basic:size", NOFOLLOW_LINKS);
    System.out.println("Size: " + size);
 } catch (IOException e) {
     System.err.println(e);
 }

  下面是一些基本的属性列表。

  • lastModifiedTime
  • lastAccessTime
  • creationTime
  • size
  • isRegularFile
  • isDirectory
  • isSymbolicLink
  • isOther
  • fileKey

  更新一个基本属性

  可以使用setTimes() 来更新任何或是所有文件的最后修改日期,上次访问日期,还有创建日期。这个方法用FileTime类的实例来表示这三个时间。如果三个参数

lastModifiedTime, lastAccessTim 或 creationTime 设置为null,那么对应的时间戳不会发生改变。

 import java.io.IOException;
 import java.nio.file.Files;
 import java.nio.file.Path;
 import java.nio.file.Paths;
 import java.nio.file.attribute.BasicFileAttributeView;
 import java.nio.file.attribute.FileTime;
 …
 Path path = Paths.get("C:/rafaelnadal/tournaments/2009", "BNP.txt");
 long time = System.currentTimeMillis();
 FileTime fileTime = FileTime.fromMillis(time);
 try {
     Files.getFileAttributeView(path,
    BasicFileAttributeView.class).setTimes(fileTime, fileTime, fileTime);
 } catch (IOException e) {
     System.err.println(e);
 }

  也可以使用Files.setLastModifiedTime()来更新文件的最后修改日期。

 long time = System.currentTimeMillis();
 FileTime fileTime = FileTime.fromMillis(time);
 try {
     Files.setLastModifiedTime(path, fileTime);
 } catch (IOException e) {
     System.err.println(e);
 }

  还有,可以使用setAttribute() 来更新文件的最后的修改时间。实际上,这个方法还可以更新文件的最后访问时间,和创建时间。

import static java.nio.file.LinkOption.NOFOLLOW_LINKS;
 …
 try {
     Files.setAttribute(path, "basic:lastModifiedTime", fileTime, NOFOLLOW_LINKS);
     Files.setAttribute(path, "basic:creationTime", fileTime, NOFOLLOW_LINKS);
     Files.setAttribute(path, "basic:lastAccessTime", fileTime, NOFOLLOW_LINKS);
 } catch (IOException e) {
     System.err.println(e);
 }

  接下来,可以使用getAttribute()方法来获取这三个时间的属性。

try {
     FileTime lastModifiedTime = (FileTime)Files.getAttribute(path,
                                 "basic:lastModifiedTime", NOFOLLOW_LINKS);
     FileTime creationTime = (FileTime)Files.getAttribute(path,
                                 "basic:creationTime", NOFOLLOW_LINKS);
     FileTime lastAccessTime = (FileTime)Files.getAttribute(path,
                                 "basic:lastAccessTime", NOFOLLOW_LINKS);

    System.out.println("New last modified time: " + lastModifiedTime);
     System.out.println("New creation time: " + creationTime);
     System.out.println("New last access time: " + lastAccessTime);

} catch (IOException e) {
       System.err.println(e);
 } 

  DOS 视图

  DOS视图在basic视图的基础上拓展四个属性,他们对应方法如下:

  • isReadOnly():
  • isHidden():
  • isArchive():
  • isSystem():

  直接上代码:

import java.io.IOException;
 import java.nio.file.Files;
 import java.nio.file.Path;
 import java.nio.file.Paths;
 import java.nio.file.attribute.DosFileAttributes;
 ...
 DosFileAttributes attr = null;
 Path path = Paths.get("C:/rafaelnadal/tournaments/2009", "BNP.txt");

try {
     attr = Files.readAttributes(path, DosFileAttributes.class);
 } catch (IOException e) {
     System.err.println(e);
 }

System.out.println("Is read only ? " + attr.isReadOnly());
 System.out.println("Is Hidden ? " + attr.isHidden());
 System.out.println("Is archive ? " + attr.isArchive());
 System.out.println("Is system ? " + attr.isSystem());

  也可以设置单一的属性,对应的属性列表如下:

  • hidden
  • readonly
  • system
  • archive

  代码演示:

import static java.nio.file.LinkOption.NOFOLLOW_LINKS;
 …
 //setting the hidden attribute to true
 try {
     Files.setAttribute(path, "dos:hidden", true, NOFOLLOW_LINKS);
 } catch (IOException e) {
     System.err.println(e);
 }

//getting the hidden attribute
try {
     boolean hidden = (Boolean) Files.getAttribute(path, "dos:hidden", NOFOLLOW_LINKS);
     System.out.println("Is hidden ? " + hidden);
 } catch (IOException e) {
      System.err.println(e);
 }

  文件拥有者视图

  大多数文件系统接受文件所有者身份的概念用于确定对象的访问权限。NIO.2通过UserPrincipal这个接口映射了这个概念,并且允许你使用FileOwnerAttributeView接口获取和设置文件的拥有者。如下面代码所示,有多种方法来获取和设置一个文件的所有者权限。

  使用Files.setOwner()方法来设置一个文件的拥有者。除了文件路径,这个方法获取UserPrincipal的实例用来映射文件拥有者的字符串表示。用户主名默认系统的服务通过FileSystem.getUserPrincipalLookupService()方法。下面是具体的例子。

import java.io.IOException;
 import java.nio.file.Files;
 import java.nio.file.Path;
 import java.nio.file.Paths;
 import java.nio.file.attribute.UserPrincipal;
 ...
 UserPrincipal owner = null;
 Path path = Paths.get("C:/rafaelnadal/tournaments/2009", "BNP.txt");
 try {
     owner = path.getFileSystem().getUserPrincipalLookupService().
                                        lookupPrincipalByName("apress"); // apress is a file owner, you can set the file owner according to you machine.
     Files.setOwner(path, owner);
 } catch (IOException e) {
     System.err.println(e);
 } 

  使用 FileOwnerAttributeView.setOwner()方法设置文件拥有者

import java.io.IOException;
 import java.nio.file.Files;
 import java.nio.file.Path;
 import java.nio.file.Paths;
 import java.nio.file.attribute.FileOwnerAttributeView;
 import java.nio.file.attribute.UserPrincipal;
 ...
 UserPrincipal owner = null;
 Path path = Paths.get("C:/rafaelnadal/tournaments/2009", "BNP.txt");
 FileOwnerAttributeView foav = Files.getFileAttributeView(path,
                                            FileOwnerAttributeView.class);
 try {
     owner = path.getFileSystem().getUserPrincipalLookupService().
                                  lookupPrincipalByName("apress");
     foav.setOwner(owner);
 } catch (IOException e) {
     System.err.println(e);
 } 

  使用Files.setAttribute()来设置文件拥有者

owner:owner, as you can see here:

import java.io.IOException;
 import java.nio.file.Files;
 import java.nio.file.Path;
 import java.nio.file.Paths;
 import java.nio.file.attribute.UserPrincipal;
 import static java.nio.file.LinkOption.NOFOLLOW_LINKS;
 …
 UserPrincipal owner = null;
 Path path = Paths.get("C:/rafaelnadal/tournaments/2009", "BNP.txt");
 try {
     owner = path.getFileSystem().getUserPrincipalLookupService().
                                  lookupPrincipalByName("apress");
     Files.setAttribute(path, "owner:owner", owner, NOFOLLOW_LINKS);
 } catch (IOException e) {
     System.err.println(e);
 } 

  使用FileOwnerAttributeView.getOwner()方法获取文件拥有者

import java.io.IOException;
 import java.nio.file.Files;
 import java.nio.file.Path;
 import java.nio.file.Paths;
 import java.nio.file.attribute.FileOwnerAttributeView;
 …
 Path path = Paths.get("C:/rafaelnadal/tournaments/2009", "BNP.txt");
 FileOwnerAttributeView foav = Files.getFileAttributeView(path,
                                         FileOwnerAttributeView.class);
 try {
     String owner = foav.getOwner().getName();
     System.out.println(owner);
 } catch (IOException e) {
     System.err.println(e);
 } 

  也可以使用 Files.getAttribute()方法获取文件的拥有者

import java.io.IOException;
 import java.nio.file.Files;
 import java.nio.file.Path;
 import java.nio.file.Paths;
 import java.nio.file.attribute.UserPrincipal;
 import static java.nio.file.LinkOption.NOFOLLOW_LINKS;
 …
 Path path = Paths.get("C:/rafaelnadal/tournaments/2009", "BNP.txt");
 try {
     UserPrincipal owner = (UserPrincipal) Files.getAttribute(path,
                                                "owner:owner", NOFOLLOW_LINKS);
     System.out.println(owner.getName());
     } catch (IOException e) {
         System.err.println(e);
     } 

  POSIX视图

  给Unix粉丝们带来了好消息。POSIX视图在继承了basic视图的基础上扩展了自己的属性。包括文件拥有者,文件所属组,以及其他9个相关的访问权限。

import java.io.IOException;
 import java.nio.file.Files;
 import java.nio.file.Path;
 import java.nio.file.Paths;
 import java.nio.file.attribute.PosixFileAttributes;
 …
 PosixFileAttributes attr = null;
 Path path = Paths.get("/home/rafaelnadal/tournaments/2009/BNP.txt");
 try {
     attr = Files.readAttributes(path, PosixFileAttributes.class);
 } catch (IOException e) {
     System.err.println(e);
 }

System.out.println("File owner: " + attr.owner().getName());
 System.out.println("File group: " + attr.group().getName());
 System.out.println("File permissions: " + attr.permissions().toString());

  也可以使用Files.getFileAttributeView()方法。

import java.nio.file.attribute.PosixFileAttributeView;
 …
 try {
     attr = Files.getFileAttributeView(path,
                  PosixFileAttributeView.class).readAttributes();
 } catch (IOException e) {
     System.err.println(e);
 } 

  permissions()方法返回了PosixFilePermissions对象的一个集合。PosixFilePermissions是一个权限帮助类。其中一个比较有用的方法是asFileAttribute(),它可以接受一个文件属性构建的权限的set对象传递给 Path.createFile()或 Path.createDirectory()方法。如下例所示,你可以获取一个文件的POSIX权限并且使用这个相同的权限去创建一个新的文件。

import java.io.IOException;
 import java.nio.file.Files;
 import java.nio.file.Path;
 import java.nio.file.Paths;
 import java.nio.file.attribute.FileAttribute;
 import java.nio.file.attribute.PosixFileAttributes;
 import java.nio.file.attribute.PosixFilePermission;
 import java.nio.file.attribute.PosixFilePermissions;
 import java.util.Set;
 …
 Path new_path = Paths.get("/home/rafaelnadal/tournaments/2009/new_BNP.txt");
 FileAttribute<Set<PosixFilePermission>> posixattrs =
                        PosixFilePermissions.asFileAttribute(attr.permissions());
 try {
     Files.createFile(new_path, posixattrs);
 } catch (IOException e) {
     System.err.println(e);
 }

  还可以使用fromString()方法传递一个硬编码的字符串权限信息。

Set<PosixFilePermission> permissions = PosixFilePermissions.fromString("rw-r--r--");
 try {
     Files.setPosixFilePermissions(new_path, permissions);
 } catch (IOException e) {
     System.err.println(e);
 }

 POSIX组拥有者

 文件组拥有者可以使用属性名为“group”来设置。setGroup()方法得到文件的路径和一个GroupPrincipal实例,这个实例映射一个字符串代表组所有者。

import java.io.IOException;
 import java.nio.file.Files;
 import java.nio.file.Path;
 import java.nio.file.Paths;
 import java.nio.file.attribute.GroupPrincipal;
 import java.nio.file.attribute.PosixFileAttributeView;
 …
 Path path = Paths.get("/home/rafaelnadal/tournaments/2009/BNP.txt");
 try {
     GroupPrincipal group = path.getFileSystem().
                getUserPrincipalLookupService().lookupPrincipalByGroupName("apressteam");
     Files.getFileAttributeView(path, PosixFileAttributeView.class).setGroup(group);
 } catch (IOException e) {
     System.err.println(e);
 }

  你可以很容易地使用Files.getAttribute()方法来获取组的属性。

import static java.nio.file.LinkOption.NOFOLLOW_LINKS;
 …
 try {
     GroupPrincipal group = (GroupPrincipal) Files.getAttribute(path, "posix:group",
                                                                        NOFOLLOW_LINKS);
     System.out.println(group.getName());
 } catch (IOException e) {
     System.err.println(e);
 }

  除此而外,还有ACL视图,文件存储视图,用户自定义视图,基本上用法跟上面视图类似,不再详叙。

  完。

  

  

时间: 2024-10-10 02:06:22

Java 7 中 NIO.2 的使用——第二节 元数据文件的属性的相关文章

Java 7 中 NIO.2 的使用——第一节 Path 类的使用

路径隶属于文件系统,实际上它是存储和组织媒体文件的格式,通常在一块或多块硬盘设备上,以便于非常容易地检索.文件系统可以通过  java.nio.file.FileSystems 这个final 类来访问,通常我们用来获取它的实例然后做我们想做的事情.FileSystems 包含下面两个非常重要的方法,还有 newFileSystem() 方法,用来构建一个新的文件系统实例. getDefault(): 这个静态方法会返回一个默认的FileSystem 给 JVM——通常是操作系统默认的文件系统.

Java 7 中 NIO.2 的使用——第四节 文件和目录

Files类提供了很多方法用于检查在于你真正实际去操作一个文件或目录.这些方法强烈推荐,也非常有用,也能避免很多异常的发生.例如,一个很好的习惯就是在你试着移动一个文件从一个地方到另一个地方的时候,先检查文件是否存在. 检查一个文件或目录是否存在 在前面的例子中已经演示到,Path实例能够有效的映射到一个文件或是目录甚至这个文件或目录物理上根本不存在.再是,Path的很多方法不会实际操作文件本身就能成功地应用.所以,事先判断一个目录或是文件存在就显得非常重要.下面有两个方法用来判断文件是否存在.

第三篇:属性_第二节:控件属性在页面及源码中的表示方式

一.属性在页面及源码中的表示方式 认真地看看页面中声明控件的代码,你会发现控件属性在页面中的表示千变万化.我们看看下面这些: <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="控件属性在页面源码中的表达方式.aspx.cs" Inherits="CustomServerControlTest.控件属性在页面源码中的表达方式" %> <!DOCT

Java Project打包,发布到Web Project下之后,运行Web Project出现找不到Java Project中资源的解决办法

要想使得web项目可以访问引用的Java Project中的资源,需要在Java Project中,将需要的IO操作的文件都放置到src目录下 法一 在Java Project中,有IO操作的类需要这样写 package cn.edu.test; import java.io.BufferedReader; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.Inp

ckeditor编辑器在java项目中配置

一.基本使用: 1.所需文件架包 A. Ckeditor基本文件包,比如:ckeditor_3.6.2.zip 下载地址:http://ckeditor.com/download 2.配置使用 A.将下载下来的CKEditor压缩解压,将解压后的文件夹("ckeditor")拷贝进项目里面,比如我是放在"WebContent"的"commons"文件夹下: B.在需要使用CKEditor的页面引入CKEditor的支持javascript <

Java的中BIO、NIO、AIO-1

Java的中BIO.NIO.AIO-1 java 最近在项目中用到TCP通信来完成命令和运行结果的交互,用的是典型的TCP通信中的C/S架构,原因很简单:在业务需求低的环境下,这种架构简单.稳定还容易写.但是在实际部署的情况下,一直出现读不到数据的空指针异常,按说BIO模式开发的应该阻塞直到有数据读取,没有找到原因就变通写了一个消息队列,使用定时器每1s从定时器中拿数据,解决了这个问题.但是想想这种同步阻塞的形式,就想了解一下其他的模式:NIO.AIO.好了,啰嗦了好多,进入正题: IO操作的基

第二节 Java Swing中的基本容器:JFrame

第二节 基本容器:JFrame 如果要使用Swing创建一个窗口,则直接使用JFrame即可,此类事Component类的子类,常用方法如下: 小试牛刀 创建一个简单的窗口 import java.awt.*; import java.io.*; import javax.swing.*; public class JavaSwingTest { public static void main(String args[]) throws IOException{ test1(); } //创建一

Java的中BIO、NIO、AIO-2

Java的中BIO.NIO.AIO-2 java 举个栗子 接上一篇接着说,C/S模式.Reactor模式.Proactor模式是服务器处理IO常用的处理模型,这一篇就来解释一下这几种模式: 以一个餐饮为例,每一个人来就餐就是一个事件,他会先看一下菜单,然后点餐.就像一个网站会有很多的请求,要求服务器做一些事情.处理这些就餐事件的就需要我们的服务人员了. 在多线程处理的方式会是这样的: 一个人来就餐,一个服务员去服务,然后客人会看菜单,点菜. 服务员将菜单给后厨. 二个人来就餐,二个服务员去服务

Java网络编程和NIO详解7:浅谈 Linux 中NIO Selector 的实现原理

Java网络编程和NIO详解7:浅谈 Linux 中NIO Selector 的实现原理 转自:https://www.jianshu.com/p/2b71ea919d49 本系列文章首发于我的个人博客:https://h2pl.github.io/ 欢迎阅览我的CSDN专栏:Java网络编程和NIO https://blog.csdn.net/column/details/21963.html 部分代码会放在我的的Github:https://github.com/h2pl/ 浅谈 Linux