1概要

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

最初にこれらの基本的な部分をより深く掘り下げたいのであれば、リンク:/java-nio-2-file-api[

File

]およびリンク:/java-nio-2-path[

Path

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の他の同等のAPIと同じように機能します。

呼び出されているオブジェクトが引数より小さい場合、負の値を返します。私たちの場合、最初の主張と同様に、作成時間はアクセス時間よりも確実に早くなります。

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

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

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


toString

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

accessed.toString();

これはISO時間形式で何か便利なものを表示します。

2016-11-24T07:52:53.376Z


setTimes(変更済み、アクセス済み、作成済み)

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

クラスの

getFileStore

APIを使用します。

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

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

userDefView.delete(attrName);


6. 結論

この記事では、Java 7 NIO.2ファイルシステムAPI(特にファイル属性API)で使用可能な、それほど一般的ではない機能について説明しました。

この記事で使用されている例の完全なソースコードはhttps://github.com/eugenp/tutorials/tree/master/core-java-io[Githubプロジェクト]にあります。