02-java nio之元文件属性

2.1 NIO2支持的视图

视图|说明 --|-- BasicFileAttributeView |所有文件系统都支持的属性,属性视图名是basic DosFileAttributeView |支持DOS属性,视图名dos,扩展basic PosixFileAttributeView |支持POSIX (Portable Operating System Interface for Unix)属性,视图名posix,扩展basic FileOwnerAttributeView |支持file owner概念的文件系统,视图名为owner AclFileAttributeView |This view supports reading or updating a file’s ACL. The NFSv4 ACL model is supported. The attribute view name is acl. UserDefinedFileAttributeView |支持用户自定义属性,视图名为user

2.2检查特定文件系统支持的视图

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支持下面5种视图:
  • acl
  • basic
  • owner
  • user
  • dos
FileStore分区和挂载点支持:
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);
}
//output
OS ---true
Data ---true
Lenovo_Recovery ---true
特定文件所支持的元文件属性
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);
}

2.3 Basic视图

2.3.1 readAttributes()获取所有的属性

BasicFileAttributes attr = null;
Path pathView = Paths.get("C:/", "test1.ini") ;
try {
   attr = Files.readAttributes(pathView , 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()) ;

File size: 506
File creation time: 2015-03-02T04:03:36.205917Z
File was last accessed at: 2015-03-02T08:08:02.034943Z
File was last modified at: 2015-03-02T08:08:02.034943Z
Is directory? false
Is regular file? true
Is symbolic link? false
Is other? false

2.3.2 获取单个属性

try {
     long size = (Long)Files.getAttribute(pathView, "basic:size", LinkOption.NOFOLLOW_LINKS);
     System.out.println("Size: " + size) ;
} catch(IOException e) {
     System.err.println(e);
}

The generally accepted form for retrieving a single attribute is [view-name:]attribute-name. The view-name is basic.
•  lastModifiedTime
•  lastAccessTime
•  creationTime
•  size
•  isRegularFile
•  isDirectory
•  isSymbolicLink
•  isOther
•  fileKey

2.3.3 更新属性

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); //3个参数分别是lastModifiedTime,lastAccessTime,createTime
} catch (IOException e) {
     System.err.println(e);
}
或者使用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);
}

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);
}

2.4 Dos视图

Dos视图扩展了basic,支持Dos或者Samba文件系统。
  • isReadOnly(): Returns the readonly attribute’s value (if true, the file can’t be deleted or updated)
  • isHidden(): Returns the hidden attribute’s value (if true, the file is not visible to the users)
  • isArchive(): Returns the archive attribute’s value (specific to backup programs)
  • isSystem(): Returns the system attribute’s value (if true, the file belongs to the operating system)
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);
     Files.setAttribute(path, "dos:hidden", true, NOFOLLOW_LINKS);
     boolean hidden = (Boolean) Files.getAttribute(path, "dos:hidden", NOFOLLOW_LINKS);
} 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());
//output
Is read only ? false
Is Hidden ? false
Is archive ? true
Is system ? false
The generally accepted form is [view-name:]attribute-name. The view-name is dos.
  • hidden
  • readonly
  • system
  • archive

2.5 FileOwner视图

2.5.1 使用Files.setOwner设置owner

UserPrincipal owner = null;
Path path = Paths.get("C:/rafaelnadal/tournaments/2009", "BNP.txt");
try {
     owner = path.getFileSystem().getUserPrincipalLookupService(). lookupPrincipalByName("apress"); //apress为权限名
     Files.setOwner(path, owner);
} catch (IOException e) {
     System.err.println(e);
}

2.5.2使用FileOwnerAttributeView.setOwner()设置owner

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);
}

2.5.3 使用Files.setAttribute()设置owner

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);
}

2.5.4 使用FileOwnerAttributeView.getOwner()获取owner

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);
}

2.5.5使用Files.getAttribute()获取owner

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);
}
The generally accepted form is [view-name:]attribute-name. The view-name is owner.只有一个owner属性。

2.6 POSIX视图

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());

try {
     attr = Files.getFileAttributeView(path, PosixFileAttributeView.class).readAttributes();
} catch (IOException e) {
     System.err.println(e);
}
The generally accepted form is [view-name:]attribute-name. The view-name is posix.

属性:

  • permissions
  • group

2.6.1 POSIX Permissions

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()创建PosixFilePermission对象集合。
Set<PosixFilePermission> permissions = PosixFilePermissions.fromString("rw-r--r--");
try {
     Files.setPosixFilePermissions(new_path, permissions);
} catch (IOException e) {
     System.err.println(e);
}

2.6.2 POSIX Group Owner

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);
}
或者
try {
     GroupPrincipal group = (GroupPrincipal) Files.getAttribute(path, "posix:group", NOFOLLOW_LINKS);
     System.out.println(group.getName());
} catch (IOException e) {
     System.err.println(e);
}

Note You can gain access to owners by calling FileOwnerAttributeView.getOwner() and FileOwnerAttributeView.setOwner() , which are inherited in the POSIX view.

2.7 ACL视图

2.7.1 使用Files.getFileAttributeView()获取ACL

List<AclEntry> acllist = null;
Path path = Paths.get("C:/rafaelnadal/tournaments/2009", "BNP.txt");
AclFileAttributeView aclview = Files.getFileAttributeView(path, AclFileAttributeView.class);
try {
     acllist = aclview.getAcl();
} catch (IOException e) {
     System.err.println(e);
}

2.7.2 使用Files.getAttribute()获取ACL

List<AclEntry> acllist = null;
Path path = Paths.get("C:/rafaelnadal/tournaments/2009", "BNP.txt");
try {
     acllist = (List<AclEntry>) Files.getAttribute(path, "acl:acl", NOFOLLOW_LINKS);
} catch (IOException e) {
     System.err.println(e);
}
The generally accepted form is [view-name:]attribute-name. The view-name is acl.

属性有:

  • acl
  • owner

2.7.3 Read ACL Entries

每个ACLentry有4个组成部分:

  • Type: Determines if the entry grants or denies access. It can be ALARM, ALLOW, AUDIT, or DENY.
  • Principal: The identity to which the entry grants or denies access. This is mapped as a UserPrincipal.
  • Permissions: A set of permissions. Mapped as Set<AclEntryPermission>.
  • Flags: A set of flags to indicate how entries are inherited and propagated. Mapped as Set<AclEntryFlag>.
for (AclEntry aclentry : acllist) {
     System.out.println("++++++++++++++++++++++++++++++++++++++++++++++++++++");
     System.out.println("Principal: " + aclentry.principal().getName());
     System.out.println("Type: " + aclentry.type().toString());
     System.out.println("Permissions: " + aclentry.permissions().toString());
     System.out.println("Flags: " + aclentry.flags().toString());
}

++++++++++++++++++++++++++++++++++++++++++++++++++++
Principal: BUILTIN\Administrators
Type: ALLOW
Permissions: [READ_ATTRIBUTES, DELETE_CHILD, WRITE_ATTRIBUTES, WRITE_ACL, WRITE_NAMED_ATTRS, WRITE_OWNER, READ_NAMED_ATTRS, DELETE, READ_DATA, EXECUTE, SYNCHRONIZE, READ_ACL, APPEND_DATA, WRITE_DATA]
Flags: []
++++++++++++++++++++++++++++++++++++++++++++++++++++
Principal: NT AUTHORITY\SYSTEM
Type: ALLOW
Permissions: [READ_ATTRIBUTES, DELETE_CHILD, WRITE_ATTRIBUTES, WRITE_ACL, WRITE_NAMED_ATTRS, WRITE_OWNER, READ_NAMED_ATTRS, DELETE, READ_DATA, EXECUTE, SYNCHRONIZE, READ_ACL, APPEND_DATA, WRITE_DATA]
Flags: []
++++++++++++++++++++++++++++++++++++++++++++++++++++
Principal: BUILTIN\Users
Type: ALLOW
Permissions: [READ_ATTRIBUTES, READ_DATA, EXECUTE, SYNCHRONIZE, READ_ACL, READ_NAMED_ATTRS]
Flags: []
++++++++++++++++++++++++++++++++++++++++++++++++++++
Principal: NT AUTHORITY\Authenticated Users
Type: ALLOW
Permissions: [READ_ATTRIBUTES, READ_DATA, EXECUTE, SYNCHRONIZE, READ_ACL, APPEND_DATA, WRITE_DATA, WRITE_ATTRIBUTES, WRITE_NAMED_ATTRS, READ_NAMED_ATTRS, DELETE]
Flags: []

2.7.4为acl赋予新的访问

If you want to grant a new access to a principal, then you must follow this process:

  1. Look up the principal by calling the FileSystem.getUserPrincipalLookupService() method.
  2. Get the ACL view (as previously described).
  3. Create a new entry by using the AclEntry.Builder object.
  4. Read the ACL (as previous described).
  5. Insert the new entry (recommended before any DENY entry).
  6. Rewrite the ACL by using setAcl() or setAttribute().
try {
     //Lookup for the principal
     UserPrincipal user = path.getFileSystem().getUserPrincipalLookupService();

     //Get the ACL view
     AclFileAttributeView view = Files.getFileAttributeView(path,  AclFileAttributeView.class);

     //Create a new entry
     AclEntry entry = AclEntry.newBuilder().setType(AclEntryType.ALLOW).
setPrincipal(user).setPermissions(AclEntryPermission.READ_DATA,                           AclEntryPermission.APPEND_DATA).build();

     //read ACL
     List<AclEntry> acl = view.getAcl();

     //Insert the new entry
     acl.add(0, entry);

     //rewrite ACL
     view.setAcl(acl);

     //or, like this
     //Files.setAttribute(path, "acl:acl", acl, NOFOLLOW_LINKS);
} catch (IOException e) {
     System.err.println(e);
}

==Note== You can gain access to owners by calling FileOwnerAttributeView.getOwner() and FileOwnerAttributeView.setOwner() , which are inherited in the ACL view.

2.8 File Store属性

2.8.1获取所有的File Store属性

FileSystem fs = FileSystems.getDefault();
for (FileStore store : fs.getFileStores()) {
     try {
          long total_space = store.getTotalSpace() / 1024;
          long used_space = (store.getTotalSpace() - store.getUnallocatedSpace()) / 1024;
          long available_space = store.getUsableSpace() / 1024;
          boolean is_read_only = store.isReadOnly();
          System.out.println("--- " + store.name() + " --- " + store.type());
          System.out.println("Total space: " + total_space);
          System.out.println("Used space: " + used_space);
          System.out.println("Available space: " + available_space);
          System.out.println("Is read only? " + is_read_only);
     } catch (IOException e) {
          System.err.println(e);
     }
}

--- OS --- NTFS
Total space: 81919996
Used space: 58143972
Available space: 23776024
Is read only? false
--- Data --- NTFS
Total space: 388543484
Used space: 112091812
Available space: 276451672
Is read only? false
--- Lenovo_Recovery --- NTFS
Total space: 16383996
Used space: 11397128
Available space: 4986868
Is read only? false

2.8.2 获取文件所在的File Store的属性

Path path = Paths.get("C:/rafaelnadal/tournaments/2009", "BNP.txt");
try {
     FileStore store = Files.getFileStore(path);
     long total_space = store.getTotalSpace() / 1024;
     long used_space = (store.getTotalSpace() - store.getUnallocatedSpace()) / 1024;
     long available_space = store.getUsableSpace() / 1024;
     boolean is_read_only = store.isReadOnly();

     System.out.println("--- " + store.name() + " --- " + store.type());
     System.out.println("Total space: " + total_space);
     System.out.println("Used space: " + used_space);
     System.out.println("Available space: " + available_space);
     System.out.println("Is read only? " + is_read_only);
} catch (IOException e) {
     System.err.println(e);
}

或者

FileStoreAttributeView fsav = store.getFileStoreAttributeView(FileStoreAttributeView.class);

2.9 用户自定义的文件属性

2.9.1 是否支持用户自定义属性

Path path = Paths.get("C:/rafaelnadal/tournaments/2009", "BNP.txt");
try {
     FileStore store = Files.getFileStore(path);
     if (!store.supportsFileAttributeView(UserDefinedFileAttributeView.class)) {
          System.out.println("The user defined attributes are not supported on: " + store);
     } else {
          System.out.println("The user defined attributes are supported on: " + store);
     }
} catch (IOException e) {
     System.err.println(e);
}

2.9.2用户自定义属性的操作

定义用户自定义属性:
Path path = Paths.get("C:/rafaelnadal/tournaments/2009", "BNP.txt");
UserDefinedFileAttributeView udfav = Files.getFileAttributeView(path, UserDefinedFileAttributeView.class);
try {
     int written = udfav.write("file.description", Charset.defaultCharset().encode("This file contains private information!"));
} catch (IOException e) {
     System.err.println(e);
}

==Note== In addition, you can write an attribute using the setAttribute() method. You can write it from a buffer or byte array ( byte[] ).

显示用户自定义属性的名称和值大小:
Path path = Paths.get("C:/rafaelnadal/tournaments/2009", "BNP.txt");
UserDefinedFileAttributeView udfav = Files.getFileAttributeView(path, UserDefinedFileAttributeView.class);
try {
     for (String name : udfav.list()) {
          System.out.println(udfav.size(name) + " " + name);
     }
} catch (IOException e) {
     System.err.println(e);
}
获取用户自定义属性的值:
Path path = Paths.get("C:/rafaelnadal/tournaments/2009", "BNP.txt");
UserDefinedFileAttributeView udfav = Files.getFileAttributeView(path, UserDefinedFileAttributeView.class);
try {
     int size = udfav.size("file.description");
     ByteBuffer bb = ByteBuffer.allocateDirect(size);
     udfav.read("file.description", bb);
     bb.flip();
     System.out.println(Charset.defaultCharset().decode(bb).toString());
} catch (IOException e) {
     System.err.println(e);
}

==Note== You can also read an attribute by using the getAttribute() method. The value is returned as byte array ( byte[] ).

删除用户自定义属性:
Path path = Paths.get("C:/rafaelnadal/tournaments/2009", "BNP.txt");
UserDefinedFileAttributeView udfav = Files.getFileAttributeView(path, UserDefinedFileAttributeView.class);
try {
     udfav.delete("file.description");
} catch (IOException e) {
     System.err.println(e);
}

猜你喜欢

转载自my.oschina.net/funcy/blog/1820872