1. 概要

この記事では、Java 7 NIO.2ファイルシステムAPIの高度な機能の1つ、特にファイル属性APIについて説明します。

これらの基本的な部分を最初に深く掘り下げたい場合は、以前にファイルおよびパスAPIについて説明しました。

ファイルシステム操作を処理するために必要なすべてのファイルは、java.nio.fileパッケージにバンドルされています。

import java.nio.file.*;

2. 基本的なファイル属性

BasicFileAttributeView によって提供されるすべてのファイルシステムに共通の基本属性の高レベルのビューから始めましょう。これは、すべての必須およびオプションの表示可能なファイル属性を格納します。

HOMEへのパスを作成し、その基本属性ビューを取得することで、現在のマシン上のユーザーのホームロケーションの基本属性を調べることができます。

String HOME = System.getProperty("user.home");
Path home = Paths.get(HOME);
BasicFileAttributeView basicView = 
  Files.getFileAttributeView(home, BasicFileAttributeView.class);

上記の手順を実行すると、1回の一括操作でポイントされたパスのすべての属性を読み取ることができます。

BasicFileAttributes basicAttribs = basicView.readAttributes();

これで、アプリケーション、特に条件文で実際に使用できるさまざまな共通属性を調べることができます。

基本属性コンテナからファイルのサイズを照会できます。

@Test
public void givenPath_whenGetsFileSize_thenCorrect() {
    long size = basicAttribs.size();
    assertTrue(size > 0);
}

ディレクトリかどうかも確認できます。

@Test
public void givenPath_whenChecksIfDirectory_thenCorrect() {
    boolean isDir = basicAttribs.isDirectory();
    assertTrue(isDir);
}

または通常のファイル:

@Test
public void givenPath_whenChecksIfFile_thenCorrect() {
    boolean isFile = basicAttribs.isRegularFile();
    assertFalse(isFile);
}

Java NIO.2を使用すると、ファイルシステム内のシンボリックリンクまたはソフトリンクを処理できるようになります。 これらは、通常ショートカットと呼ばれるファイルまたはディレクトリです。

ファイルがシンボリックリンクであるかどうかを確認するには、次の手順に従います。

@Test
public void givenPath_whenChecksIfSymLink_thenCorrect() {
    boolean isSymLink = basicAttribs.isSymbolicLink();
    assertFalse(isSymLink);
}

まれに、 isOther APIを呼び出して、ファイルが通常のファイル、ディレクトリ、またはシンボリックリンクの一般的なカテゴリのいずれにも属していないかどうかを確認できます。

@Test
public void givenPath_whenChecksIfOther_thenCorrect() {
    boolean isOther = basicAttribs.isOther();
    assertFalse(isOther);
}

ファイルが作成された時間を取得するには:

FileTime created = basicAttribs.creationTime();

最終変更時刻を取得するには:

FileTime modified = basicAttribs.lastModifiedTime();

そして、最後のアクセス時間を取得するには:

FileTime accessed = basicAttribs.lastAccessTime();

上記のすべての例は、FileTimeオブジェクトを返します。 これは、単なるタイムスタンプよりも使いやすい抽象化です。

たとえば、2つのファイル時間を簡単に比較して、どちらのイベントが前後に発生したかを知ることができます。

@Test
public void givenFileTimes_whenComparesThem_ThenCorrect() {
    FileTime created = basicAttribs.creationTime();
    FileTime modified = basicAttribs.lastModifiedTime();
    FileTime accessed = basicAttribs.lastAccessTime();

    assertTrue(0 >= created.compareTo(accessed));
    assertTrue(0 <= modified.compareTo(created));
    assertTrue(0 == created.compareTo(created));
}

compareTo APIは、Javaの他の同等のものと同じように機能します。 呼び出されているオブジェクトが引数よりも小さい場合は、負の値を返します。 私たちの場合、最初のアサーションのように、作成時間は間違いなくアクセス時間の前になります。

2番目のアサーションでは、作成イベントの後でのみ変更を行うことができるため、正の整数値を取得します。 そして最後に、比較される時間が等しい場合は0を返します。

FileTimeオブジェクトがある場合、必要に応じてそれを他のほとんどの単位に変換できます。 日、時間、分、秒、ミリ秒など。 これを行うには、適切なAPIを呼び出します。

accessed.to(TimeUnit.SECONDS);
accessed.to(TimeUnit.HOURS);
accessed.toMillis();

toString APIを呼び出すことで、人間が読める形式のファイル時間を印刷することもできます。

accessed.toString();

これは、ISO時間形式で役立つものを出力します。

2016-11-24T07:52:53.376Z

また、その setTimes(modified、accessed、created) APIを呼び出すことにより、ビューの時間属性を変更することもできます。 変更したい場所に新しいFileTimeオブジェクトを渡すか、変更したくない場所にnullを渡します。

最終アクセス時間を1分先に変更するには、次の手順に従います。

FileTime newAccessTime = FileTime.fromMillis(
  basicAttribs.lastAccessTime().toMillis() + 60000);
basicView.setTimes(null, newAccessTime , null);

この変更は、マシン上で実行され、ファイルシステムを使用している他のアプリケーションから見た場合、実際のファイルに保持されます。

3. ファイルスペース属性

Windows、Linux、またはMacでマイコンピュータを開くと、通常、ストレージドライブに関するスペース情報のグラフィック分析が表示されます。

Java NIO.2は、この種の高レベルの機能を非常に簡単にします。 単純なAPIを呼び出すだけで、基盤となるファイルシステムと対話してこの情報を取得します。

FileStore クラスを使用して、ストレージドライブを検査し、サイズ、使用されているスペースの量、未使用の量などの重要な情報を取得できます。

ファイルシステム内の任意のファイルの場所のFileStoreインスタンスを取得するには、FilesクラスのgetFileStoreAPIを使用します。

Path file = Paths.get("file");
FileStore store = Files.getFileStore(file);

このFileStoreインスタンスは、ファイル自体ではなく、指定されたファイルが配置されているファイルストアを具体的に表します。 合計スペースを取得するには:

long total = store.getTotalSpace();

使用済みスペースを取得するには:

long used = store.getTotalSpace() - store.getUnallocatedSpace();

このアプローチに従う可能性は、次のアプローチよりも低くなります。

より一般的には、すべてのファイルストアに関するストレージ情報に関する情報を取得する可能性があります。 プログラムでマイコンピュータののグラフィックドライブスペース情報をエミュレートするには、FileSystemクラスを使用してファイルストアを列挙します。

Iterable<FileStore> fileStores = FileSystems.getDefault().getFileStores();

次に、戻り値をループして、グラフィカルユーザーインターフェイスの更新など、情報を処理するために必要なことをすべて実行できます。

for (FileStore fileStore : fileStores) {
    long totalSpace = fileStore.getTotalSpace();
    long unAllocated = fileStore.getUnallocatedSpace();
    long usable = fileStore.getUsableSpace();
}

すべての戻り値はバイト単位であることに注意してください。 基本的な演算を使用して、適切な単位に変換したり、使用済みスペースなどの他の情報を計算したりできます。

未割り当て領域と使用可能領域の違いは、JVMへのアクセス可能性にあります。

使用可能なスペースはJVMで使用可能なスペースであり、未割り当てのスペースは基になるファイルシステムから見た使用可能なスペースです。 そのため、使用可能なスペースが未割り当てのスペースよりも小さい場合があります。

4. ファイル所有者の属性

ファイルの所有権情報を検査するには、FileOwnerAttributeViewインターフェースを使用します。 それは私たちに所有権情報の高レベルのビューを提供します。

次のようにFileOwnerAttributeViewオブジェクトを作成できます。

Path path = Paths.get(HOME);
FileOwnerAttributeView ownerView = Files.getFileAttributeView(
  attribPath, FileOwnerAttributeView.class);

上記のビューからファイルの所有者を取得するには:

UserPrincipal owner = ownerView.getOwner();

他の任意の目的で所有者の名前を取得することを除けば、上記のオブジェクトを使用してプログラムで実行できることは実際にはほとんどありません。

String ownerName = owner.toString();

5. ユーザー定義のファイル属性

ファイルシステムで定義されたファイル属性がニーズに対して十分でないシナリオがあります。 このような場合に遭遇し、ファイルに独自の属性を設定する必要がある場合は、UserDefinedFileAttributeViewインターフェイスが便利です。

Path path = Paths.get("somefile");
UserDefinedFileAttributeView userDefView = Files.getFileAttributeView(
  attribPath, UserDefinedFileAttributeView.class);

上記のビューで表されるファイルに対してすでに定義されているユーザー定義属性のリストを取得するには、次のようにします。

List<String> attribList = userDefView.list();

ファイルにユーザー定義属性を設定するには、次のイディオムを使用します。

String name = "attrName";
String value = "attrValue";
userDefView.write(name, Charset.defaultCharset().encode(value));

ユーザー定義の属性にアクセスする必要がある場合は、ビューによって返される属性リストをループして、次のイディオムを使用してそれらを検査できます。

ByteBuffer attrValue = ByteBuffer.allocate(userView.size(attrName));
userDefView.read(attribName, attribValue);
attrValue.flip();
String attrValue = Charset.defaultCharset().decode(attrValue).toString();

ファイルからユーザー定義属性を削除するには、ビューのdeleteAPIを呼び出すだけです。

userDefView.delete(attrName);

6. 結論

この記事では、Java 7 NIO.2ファイルシステムAPI、特にファイル属性APIで使用できるあまり一般的ではない機能のいくつかについて説明しました。

この記事で使用されている例の完全なソースコードは、Githubプロジェクトで入手できます。