Java文件屬性

Files類可以訪問常用的文件屬性。Files.isHidden(Path p)方法測試文件是否被隱藏。
Files類中的以下方法可以訪問各種類型文件的常用屬性。

long size(Path)
boolean isHidden(Path path)
boolean isRegularFile(Path path, LinkOption... options)
boolean isDirectory(Path path, LinkOption... options)
boolean isSymbolicLink(Path path)
FileTime getLastModifiedTime(Path path, LinkOption... options)

文件屬性

java.nio.attribute包中包含文件屬性相關的類。它在以下六種類型的視圖中捆綁文件屬性。

BasicFileAttributeView管理基本文件屬性,如創建時間,上次訪問時間,上次修改時間,大小,文件類型(常規文件,目錄,符號鏈接或其他)和文件鍵(文件的唯一編號)。 所有平臺都支持此視圖。

DosFileAttributeView擴展BasicFileAttributeView訪問特定於DOS文件屬性。 它提供了支持以檢查文件是否是隱藏文件,系統文件,歸檔文件和只讀文件。 它僅在支持DOS系統(如Microsoft Windows)上可用。

POSIX代表UNIX的便攜式操作系統接口。 PosixFileAttributeView擴展了BasicFileAttributeView,並添加了對支持POSIX標準(如UNIX)的系統上可用的屬性的支持。它允許我們管理所有者,組和[相關訪問]權限。

FileOwnerAttributeView管理文件的所有者。ACL代表訪問控制列表。 AclFileAttributeView管理文件的ACL。UserDefinedFileAttributeView管理一組文件的用戶定義屬性。 屬性的名稱是一個字符串。屬性的值可以是任何數據類型。

文件屬性視圖支持

FileStore類的supportsFileAttributeView()方法告訴文件存儲器是否支持特定文件屬性視圖。如果支持指定的文件屬性視圖,則返回true; 否則,返回false

以下代碼顯示如何檢查文件屬性支持。

import java.nio.file.FileStore;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.attribute.PosixFileAttributeView;

public class Main {
  public static void main(String[] args) throws Exception {
    Path path = Paths.get("");
    FileStore fs = Files.getFileStore(path);

    // Check if POSIX file attribute is supported by the file store
    boolean supported = fs
        .supportsFileAttributeView(PosixFileAttributeView.class);
    if (supported) {
      System.out.println("POSIX file attribute view  is supported.");
    } else {
      System.out.println("POSIX file attribute view  is not  supported.");
    }

  }
}

上面的代碼生成以下結果。

POSIX file attribute view  is not  supported.

示例

以下代碼顯示如何檢查文件存儲的支持的文件屬性視圖。

import java.io.IOException;
import java.nio.file.FileStore;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.attribute.AclFileAttributeView;
import java.nio.file.attribute.BasicFileAttributeView;
import java.nio.file.attribute.DosFileAttributeView;
import java.nio.file.attribute.FileAttributeView;
import java.nio.file.attribute.FileOwnerAttributeView;
import java.nio.file.attribute.PosixFileAttributeView;
import java.nio.file.attribute.UserDefinedFileAttributeView;

public class Main {
  public static void main(String[] args) {
    Path path = Paths.get("C:");

    try {
      FileStore fs = Files.getFileStore(path);
      printDetails(fs, AclFileAttributeView.class);
      printDetails(fs, BasicFileAttributeView.class);
      printDetails(fs, DosFileAttributeView.class);
      printDetails(fs, FileOwnerAttributeView.class);
      printDetails(fs, PosixFileAttributeView.class);
      printDetails(fs, UserDefinedFileAttributeView.class);
    } catch (IOException ex) {
      ex.printStackTrace();
    }
  }

  public static void printDetails(FileStore fs,
      Class<? extends FileAttributeView> attribClass) {
    boolean supported = fs.supportsFileAttributeView(attribClass);
    System.out.format("%s is  supported: %s%n", attribClass.getSimpleName(),
        supported);
  }
}

上面的代碼生成以下結果。

AclFileAttributeView is  supported: true
BasicFileAttributeView is  supported: true
DosFileAttributeView is  supported: true
FileOwnerAttributeView is  supported: true
PosixFileAttributeView is  supported: false
UserDefinedFileAttributeView is  supported: true

讀取和更新文件屬性

要讀取或更新一個文件屬性,請使用Files類。Files類具有以下兩種靜態方法,使用屬性名稱作爲字符串來讀取和更新文件屬性:

Object getAttribute(Path path, String attribute, LinkOption... options)
Path setAttribute(Path path, String attribute, Object value, LinkOption... options)

要讀取或更新文件的多個屬性,請使用特定的文件屬性視圖。對於大多數文件屬性視圖,可使用名爲TypeAttributesTypeAttributeView這兩個接口。對於基本文件屬性,有BasicFileAttributesBasicFileAtrributeView接口。TypeAttributes讀取屬性。TypeAttributeView讀取/更新屬性。
以下是Files類兩個方法批量讀取文件屬性。

<A extends BasicFileAttributes> A readAttributes(Path path, Class<A> type, LinkOption... options)

Map<String,Object> readAttributes(Path path, String attributes, LinkOption... options)

兩種方法的最後一個參數指定如何處理符號鏈接。默認情況下,如果文件是符號鏈接,則讀取符號鏈接的目標屬性。
如果指定NOFOLLOW_LINKS作爲選項,則讀取符號鏈接的屬性,而不是其目標的屬性。

第一個readAttributes()方法返回TypeAttributes對象中指定類型的所有文件屬性。創建表示文件路徑的Path對象

Path  path   = Paths.get("C:\\Java_Dev\\test1.txt");

讀取基本文件屬性

BasicFileAttributes bfa  = Files.readAttributes(path, BasicFileAttributes.class);

獲取上次修改時間

FileTime lastModifiedTime  = bfa.lastModifiedTime();

獲取文件的大小

long  size = bfa.size();

第二個readAttributes()方法返回特定類型的所有或部分屬性。要讀取的屬性列表以字符串形式提供。 屬性列表的字符串形式使用以下語法:

view-name:comma-separated-attributes

view-name是要讀取的屬性視圖的名稱,例如basicposixacl等。如果省略view-name,則默認爲basic。 如果view-name存在,它後面跟一個冒號。

通過將星號指定爲屬性列表,可以讀取特定視圖類型的所有屬性。 例如,可以指定「basic:*」或「*」來讀取所有基本文件屬性。要讀取基本視圖的大小和最後修改時間,可使用 -

"basic:size,lastModifiedTime" or "size,lastModifiedTime".

要使用ACL視圖讀取文件的owner屬性,那麼可使用字符串「acl:owner」。要讀取文件的所有posix屬性,那麼可使用「posix:*」。
以下代碼打印文件 C:\Java_Dev\test1.txt 的大小和最後修改時間。

import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Map;

public class Main {
  public static void main(String[] args) throws Exception {
    Path path = Paths.get("C:\\Java_Dev\\test1.txt");

    // Prepare the attribute list
    String attribList = "basic:size,lastModifiedTime";

    // Read the attributes
    Map<String, Object> attribs = Files.readAttributes(path, attribList);

    System.out.format("Size:%s, Last   Modified   Time:%s %n",
        attribs.get("size"), attribs.get("lastModifiedTime"));

  }
}

實例-2

以下代碼讀取文件C:\Java_Dev\test1.txt的基本文件屬性,並在標準輸出上打印其中的一些。

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;

public class Main {
  public static void main(String[] args) {
    Path path = Paths.get("C:\\Java_Dev\\test1.txt");

    try {
      BasicFileAttributes bfa = Files.readAttributes(path,
          BasicFileAttributes.class);
      System.out.format("Size:%s bytes %n", bfa.size());
      System.out.format("Creation Time:%s %n", bfa.creationTime());
      System.out.format("Last Access  Time:%s %n", bfa.lastAccessTime());
    } catch (IOException e) {
      e.printStackTrace();
    }
  }
}

還可以使用指定的視圖對象讀取文件屬性。使用如下的Files類的getFileAttributeView()方法來獲取特定的屬性視圖。如果文件屬性視圖不可用,則返回null

<V extends FileAttributeView> V  getFileAttributeView(Path path,  Class<V> type, LinkOption... options)

獲得特定視圖類型的視圖對象後,可以使用視圖對象的readAttributes()方法讀取該視圖類型的所有屬性。

實施例3

以下代碼使用基本視圖對象讀取C:\Java_Dev\test1.txt文件的所有基本屬性:

Path  path   = Paths.get("C:\\Java_Dev\\test1.txt");
BasicFileAttributeView bfv = Files.getFileAttributeView(path,  BasicFileAttributeView.class);
BasicFileAttributes bfa  = bfv.readAttributes();

以下代碼顯示如何使用基本文件屬性視圖來讀取和更新基本文件屬性。

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.BasicFileAttributes;
import java.nio.file.attribute.FileTime;
import java.time.Instant;

public class Main {
  public static void main(String[] args) {
    Path path = Paths.get("C:\\Java_Dev\\test1.txt");

    try {
      BasicFileAttributeView bfv = Files.getFileAttributeView(path,
          BasicFileAttributeView.class);
      BasicFileAttributes bfa = bfv.readAttributes();

      System.out.format("Size:%s bytes %n", bfa.size());
      System.out.format("Creation  Time:%s %n", bfa.creationTime());
      System.out.format("Last Access  Time:%s %n", bfa.lastAccessTime());

      FileTime newLastModifiedTime = null;
      FileTime newLastAccessTime = null;
      FileTime newCreateTime = FileTime.from(Instant.now());

      bfv.setTimes(newLastModifiedTime, newLastAccessTime, newCreateTime);
    } catch (IOException e) {
      e.printStackTrace();
    }
  }
}