このページを正しく表示するには、ブラウザでJavaScriptを有効にする必要があります。
コース: 重要なクラス
レッスン: 基本的なI/O
セクション: ファイルI/O(NIO.2を含む)
メタデータの管理(ファイル属性とファイル・ストア属性)
ホームページ > 重要なクラス > 基本的なI/O

メタデータの管理(ファイル属性とファイル・ストア属性)

メタデータの定義は、"他のデータに関するデータ"です。 ファイル・システムでは、データはファイルやディレクトリに含まれ、この各オブジェクトに関する情報がメタデータに記録されます。 記録される情報には、オブジェクトの種類(通常のファイル、ディレクトリ、リンク)、サイズ、作成日、最終更新日、ファイル所有者、アクセス権限などがあります。

ファイル・システムのメタデータは通常、ファイル属性と呼ばれます。 Filesクラスには、ファイルの1つの属性の取得や設定に使用できる、以下のようなメソッドがあります。

メソッド 説明
size(Path) 指定したファイルのサイズをバイト単位で返します。
isDirectory(Path, LinkOption) 指定したPathによって特定されるファイルがディレクトリである場合に、trueを返します。
isRegularFile(Path, LinkOption...) 指定したPathによって特定されるファイルが通常のファイルである場合に、trueを返します。
isSymbolicLink(Path) 指定したPathによって特定されるファイルがシンボリック・リンクである場合に、trueを返します。
isHidden(Path) 指定したPathによって特定されるファイルが、ファイル・システム上の隠しファイルである場合に、trueを返します。
getLastModifiedTime(Path, LinkOption...)
setLastModifiedTime(Path, FileTime)
指定したファイルの最終更新日時を返します。またはそれを設定します。
getOwner(Path, LinkOption...)
setOwner(Path, UserPrincipal)
ファイルの所有者を返します。またはそれを設定します。
getPosixFilePermissions(Path, LinkOption...)
setPosixFilePermissions(Path, Set<PosixFilePermission>)
ファイルのPOSIXファイル権限を返します。またはそれを設定します。
getAttribute(Path, String, LinkOption...)
setAttribute(Path, String, Object, LinkOption...)
ファイル属性の値を返します。またはそれを設定します。

プログラムで、ほぼ同じタイミングで複数のファイル属性を必要とする場合、1つの属性を取得するメソッドを使用するのは非効率的です。 1つの属性を取得するために繰り返しファイル・システムにアクセスすると、パフォーマンスが低下する恐れがあります。 この理由から、Filesクラスには、1回の一括操作でファイルの複数の属性を取得するreadAttriutesメソッドが2種類用意されています。

メソッド 説明
readAttributes(Path, String, LinkOption...) ファイルの複数の属性を一括操作で読み取ります。 読み取る属性をStringパラメータに指定します。
readAttributes(Path, Class<A>, LinkOption...) ファイルの複数の属性を一括操作で読み取ります。 Class<A>パラメータは取得する属性のクラスです。このメソッドは、ここに指定したクラスのオブジェクトを返します。

readAttributesメソッドを使用したサンプルを確認する前に、記録する必要のある属性に関する概念はファイル・システムごとに異なるということを理解してください。 この理由で、関連するファイル属性はビューにまとめられています。 ビューは、POSIXやDOSなどの特定のファイル・システム実装、またはファイル所有権などの一般的な機能に関連付けられます。

サポートされるビューは次のとおりです。

ファイル・システム実装で基本的なファイル属性ビューしかサポートされない場合もあれば、複数のファイル属性ビューがサポートされる場合もあります。 このAPIに含まれていないその他の属性ビューがサポートされる場合もあります。

ほとんどの場合、FileAttributeViewインタフェースを直接操作する必要はありません。 (FileAttributeViewインタフェースを直接操作する必要がある場合は、getFileAttributeView(Path, Class<V>, LinkOption...)メソッドを使用してアクセスできます。)

ジェネリクス(総称型)を使用したreadAttributesメソッドを利用すると、任意のファイル属性ビューの属性を読み取ることができます。 以降のサンプルでは、readAttributesメソッドを使用します。

このセクションでは、これ以降、次の内容について説明します。

基本的なファイル属性

上で説明したとおり、ファイルの基本的な属性を読み取る場合は、Files.readAttributesメソッドのいずれかを使用できます。これらのメソッドは、1回の一括操作ですべての基本的な属性を読み取ります。 これは、属性を1つずつファイル・システムにアクセスして読み取るよりもはるかに効率的です。 現在、可変引数にはLinkOption列挙型の定数であるNOFOLLOW_LINKSを使用できます。 シンボリック・リンクをたどらない場合は、このオプションを使用してください。


タイムスタンプに関する注意事項:基本的な属性セットには、creationTimelastModifiedTimelastAccessTimeという3つのタイムスタンプが含まれます。 これらのタイムスタンプは、特定の実装でサポートされないことがあります。この場合、対応するアクセッサ・メソッドは実装固有の値を返します。 サポートされる場合は、タイムスタンプはFileTimeオブジェクトとして返されます。

次のコードでは、BasicFileAttributesクラスのメソッドを使用して、あるファイルに関する基本的なファイル属性を読み取って出力します。

Path file = ...;
BasicFileAttributes attr = Files.readAttributes(file, BasicFileAttributes.class);

System.out.println("creationTime: " + attr.creationTime());
System.out.println("lastAccessTime: " + attr.lastAccessTime());
System.out.println("lastModifiedTime: " + attr.lastModifiedTime());

System.out.println("isDirectory: " + attr.isDirectory());
System.out.println("isOther: " + attr.isOther());
System.out.println("isRegularFile: " + attr.isRegularFile());
System.out.println("isSymbolicLink: " + attr.isSymbolicLink());
System.out.println("size: " + attr.size());

このサンプル・コードで使用されているアクセッサ・メソッドのほかに、fileKeyメソッドがあります。このメソッドは、ファイルを一意に特定するオブジェクトを返すか、ファイル・キーが利用できない場合はnullを返します。

タイムスタンプの設定

次のコードでは、最終更新日時をミリ秒単位で設定します。

Path file = ...;
BasicFileAttributes attr = Files.readAttributes(file, BasicFileAttributes.class);
long currentTime = System.currentTimeMillis();
FileTime ft = FileTime.fromMillis(currentTime);
Files.setLastModifiedTime(file, ft);
}

DOSファイル属性

DOSファイル属性は、SambaなどのDOS以外のファイル・システムでもサポートされます。 次のコードでは、DosFileAttributesクラスのメソッドを使用しています。

Path file = ...;
try {
    DosFileAttributes attr = Files.readAttributes(file, DosFileAttributes.class);
    System.out.println("isReadOnly is " + attr.isReadOnly());
    System.out.println("isHidden is " + attr.isHidden());
    System.out.println("isArchive is " + attr.isArchive());
    System.out.println("isSystem is " + attr.isSystem());
} catch (UnsupportedOperationException x) {
    System.err.println("DOS file attributes not supported:" + x);
}

一方、DOS属性を設定するときは、次のようにsetAttribute(Path, String, Object, LinkOption...)メソッドを使用できます。

Path file = ...;
Files.setAttribute(file, "dos:hidden", true);

POSIXファイル権限

POSIXは、Portable Operating System Interface for UNIXの略称であり、さまざまなUNIX系オペレーティング・システム間の相互運用性を確保する目的で策定されたIEEE標準およびISO標準のセットです。 これらのPOSIX標準に従っているプログラムは、他のPOSIX互換オペレーティング・システムに容易に移植できます。

POSIXでは、ファイル所有者とグループ所有者に加えて、9つのファイル権限がサポートされています。 この9つの権限とは、ファイル所有者の読取り権限、書込み権限、実行権限、同じグループのメンバーの読取り権限、書込み権限、実行権限、"その他すべての人"の読取り権限、書込み権限、実行権限です。

次のコードでは、あるファイルに関するPOSIXファイル属性を読み取って、標準出力に出力します。 このコードでは、PosixFileAttributesクラスのメソッドを使用しています。

Path file = ...;
PosixFileAttributes attr = Files.readAttributes(file, PosixFileAttributes.class);
System.out.format("%s %s %s%n", attr.owner().getName, attr.group().getName(),
                  PosixFilePermissions.toString(attr.permissions()));

PosixFilePermissionsヘルパー・クラスには、次のようないくつかの便利なメソッドが用意されています。

次のコードでは、あるファイルから属性を読み取り、その属性を割り当てた新しいファイルを作成しています。

Path sourceFile = ...;
Path newFile = ...;
PosixFileAttributes attrs = Files.readAttributes(sourceFile, PosixFileAttributes.class);
FileAttribute<Set<PosixFilePermission>> attr =
          PosixFilePermissions.asFileAttribute(attrs.permissions());
Files.createFile(file, attr);

asFileAttributeメソッドを使用して、権限をFileAttributeでラップします。 次に、これらの権限が設定された新しいファイルを作成します。 umaskも適用されることに注意してください。これによって、新しいファイルは要求された権限よりもセキュアとなる可能性があります。

ハードコード文字列で表された値を使用してファイルの権限を設定するには、次のようなコードを使用できます。

Path file = ...;
Set<PosixFilePermission> perms = PosixFilePermissions.fromString("rw-------");
FileAttribute<Set<PosixFilePermission>> attr = PosixFilePermissions.asFileAttribute(perms);
Files.setPosixFilePermissions(file, perms);

サンプル・プログラムのChmodでは、chmodユーティリティと同様の動作で、ファイルの権限を再帰的に変更します。

ファイル所有者またはグループ所有者の設定

ある名前を、ファイル所有者やグループ所有者として保存できるオブジェクトに変換する場合は、UserPrincipalLookupServiceサービスを使用できます。 このサービスは、名前またはグループ名を文字列として検索し、その文字列を表すUserPrincipalオブジェクトを返します。 デフォルトのファイル・システム向けのユーザー・プリンシパル検索サービスは、FileSystem.getUserPrincipalLookupServiceメソッドを使用して取得できます。

次のコードでは、setOwnerメソッドを使用してファイル所有者を設定しています。

Path file = ...;
UserPrincipal owner = file.GetFileSystem().getUserPrincipalLookupService()
                          .lookupPrincipalByName("sally");
Files.setOwner(file, owner);

Filesクラスには、グループ所有者を設定するための専用メソッドはありません。 POSIXファイル属性ビューを次のように使用することで、安全に直接設定できます。

Path file = ...;
GroupPrincipal group = file.getFileSystem().getUserPrincipalLookupService()
                           .lookupPrincipalByGroupName("green");
Files.getFileAttributeView(file, PosixFileAttributeView.class).setGroup(group);

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

お使いのファイル・システム実装でサポートされるファイル属性がニーズに合わない場合は、UserDefinedAttributeViewを使用して独自のファイル属性を作成し、記録できます。

一部の実装では、この概念はNTFS代替データ・ストリーム(ADS)などの機能や、ext3やZFSなどのファイル・システム上の拡張属性に関連付けられています。 ほとんどの実装では値のサイズが制限されます。たとえば、ext3ではこのサイズは4キロバイトに制限されています。

ファイルのMIMEタイプは、次のようなコードを使用して、ユーザー定義属性として保存できます。

Path file = ...;
UserDefinedFileAttributeView view = Files
    .getFileAttributeView(file, UserDefinedFileAttributeView.class);
view.write("user.mimetype", Charset.defaultCharset().encode("text/html");

MIMEタイプ属性を読み取るには、次のようなコードを使用します。

Path file = ...;
UserDefinedFileAttributeView view = file
    .getFileAttributeView(UserDefinedFileAttributeView.class);
String name = "user.mimetype";
ByteBuffer buf = ByteBuffer.allocate(view.size(name));
view.read(name, buf);
buf.flip();
String value = Charset.defaultCharset().decode(buf).toString();

サンプル・プログラムのXddでは、ユーザー定義属性の取得、設定、削除の方法を示しています。


注:Linuxでは、ユーザー定義属性を動作させるには、拡張属性の有効化が必要となる場合があります。 ユーザー定義属性ビューへのアクセス時にUnsupportedOperationExceptionが発生する場合は、ファイル・システムを再マウントする必要があります。 次のコマンドは、ext3ファイル・システム向けの拡張属性を設定してルート・パーティションを再マウントします。 お使いのLinux系オペレーティング・システムでこのコマンドが動作しない場合は、オペレーティング・システムの資料を確認してください。

$ sudo mount -o remount,user_xattr /
変更を永続化する場合は、/etc/fstabにエントリを追加します。

ファイル・ストア属性

FileStoreクラスを使用して、利用可能な領域などのファイル・ストアに関する情報を取得できます。 getFileStore(Path)メソッドは、指定したファイルのファイル・ストアを取得します。

次のコードは、特定のファイルが保存されているファイル・ストアの使用領域を出力します。

Path file = ...;
FileStore store = Files.getFileStore(file);

long total = store.getTotalSpace() / 1024;
long used = (store.getTotalSpace() - store.getUnallocatedSpace()) / 1024;
long avail = store.getUsableSpace() / 1024;

サンプル・プログラムのDiskUsageでは、このAPIを使用して、デフォルトのファイル・システム内のすべてのストアに関するディスク領域情報を出力します。 このプログラムでは、FileSystemクラスのgetFileStoresメソッドを使用して、ファイル・システムのすべてのファイル・ストアを取得しています。


サンプル・プログラムで問題が発生した場合は、 『Compiling and Running the Examples: FAQs』を参照してください。
フィードバックをお寄せください。さまざまなご意見をお待ちしております。

前のページ: ファイルやディレクトリの移動
次のページ: ファイルの読取り、書込み、作成