Java nio の API を見ていくシリーズ(目次)。 今回はファイル、ディレクトリのプロパティや属性を取得・設定するメソッドを見ていきます。 ただし、メソッド名に “Attribute” がつくメソッド(readAttribute(), setAttribute() など)は次回に。 今回見ていくのは
です。
Files クラスの宣言
今回見ていく Files クラスのメソッドは以下のものです:package java.nio.file; public final Class Files{ ... // isXxxx() メソッド public static boolean isRegularFile(Path path, LinkOption... options) public static boolean isDirectory(Path path, LinkOption... options) public static boolean isSymbolicLink(Path path) public static boolean isExecutable(Path path) public static boolean isHidden(Path path) public static boolean isSameFile(Path path, Path path2) // ファイル・サイズ public static long size(Path path) // 最終更新時刻 public static FileTime getLastModifiedTime(Path path, LinkOption... options) public static Path setLastModifiedTime(Path path, FileTime time) // ファイル所有者 public static UserPrincipal getOwner(Path path, LinkOption... options) public static Path setOwner(Path path, UserPrincipal owner) // POSIX ファイル権限 public static Set<PosixFilePermission> getPosixFilePermissions(Path path, LinkOption... options) public static Path setPosixFilePermissions(Path path, Set<PosixFilePermission> perms) }
- isXxxx() メソッドの中で、前回見た isReadable(), isWritable() メソッドは飛ばしてます。
isXxxx() メソッド
メソッド | 返り値 | 説明 |
---|---|---|
isRegularFile(Path, LinkOption...) | boolean | 引数の Path が通常のファイルかどうかをテスト |
isDirectory(Path, LinkOption...) | boolean | 引数の Path がディレクトリかどうかをテスト |
isSymbolicLink(Path) | boolean | 引数の Path がシンボリック・リンクかどうかをテスト |
isExecutable(Path) | boolean | 引数の Path が実行可能かどうかをテスト ファイルが存在するかチェック JVM が実行できる権限を持っているかもチェックする |
isHidden(Path) | boolean | 引数の Path が隠しファイルかどうかをテスト アルゴリズムはファイルシステムに依存する*1 |
isSameFile(Path, Path) | boolean | 2つの引数の Path が同じものかどうかをテスト ファイルが存在するかどうかはチェックされない |
ではいくつかの isXxxx() メソッドを使うサンプル・コード。 前回は Groovy で try-with-resources 文がサポートされてない*2ので Java で書きましたが、今回はまた Groovy で書いてます:
import java.nio.file.* import java.nio.charset.Charset // 準備 def dir = Paths.get("dir") Files.createDirectories(dir) def src = dir.resolve("source.java") Files.deleteIfExists(src) Files.createFile(src) Files.write(src, ["first line", "second line", "third line"], Charset.defaultCharset()) // isRegularFile(), isDirectory() メソッド assert Files.isRegularFile(src) && !Files.isDirectory(src) assert !Files.isRegularFile(dir) && Files.isDirectory(dir) // isExecutable() 実行可能? // ${JAVA_HOME}/bin/javac.exe (exe ファイル) def javac = Paths.get(System.getenv("JAVA_HOME")).resolve("bin/javac.exe") assert Files.isExecutable(javac) // isSameFile() 同じファイルかどうかテスト def path = Paths.get("C:/sample/code/of/java/nio/file/dir/source.java") assert Files.isSameFile(src, path)
- isExecutable() を使っている箇所では、環境変数 JAVA_HOME に Java のインストールフォルダを設定していないとアサーションを通りません
- isSameFile() を使っている箇所では、スクリプトが「C:/sample/code/of/java/nio/file」フォルダで実行していなければアサーションを通りません
ファイル・サイズ
ファイル・サイズを取得するメソッド。 返り値は long 値です。メソッド | 返り値 | 説明 |
---|---|---|
size(Path) | long | ファイル・サイズを取得する |
サンプル・コード・・・あんまり意味ないかな?:
import java.nio.file.Files // 準備 def src = ... println Files.size(src)
最終更新時刻
最終更新日時を取得・設定するメソッドメソッド | 返り値 | 説明 |
---|---|---|
getLastModifiedTime(Path, LinkOption...) | FileTime | 最終更新時刻を返す |
setLastModifiedTime(Path path, FileTime time) | Path | 最終更新時刻を設定する |
更新時刻は java.nio.file.attribute.FileTime 型のオブジェクトを介して取得設定します。 FileTime クラスの定義はこんなの:
package java.nio.file.attribute; import java.util.concurrent.TimeUnit; public class FileTime implements Comparable<FileTime>{ // このオブジェクトが表す時刻を long 値で返す public long to(TimeUnit unit) public long toMillis() // 【static ファクトリ・メソッド】 引数の long 値で表される時刻の FileTime オブジェクトを返す public static FileTime from(long value, TimeUnit unit) public static FileTime fromMillis(long value) // Object クラスのメソッドをオーバーライド public boolean equals(Object obj) // null でなく同じ時刻なら true public int hashCode() public String toString() // Comparable インターフェースのメソッドをオーバーライド public int compareTo(FileTime other) // 時間順序で大小評価
FileTime オブジェクトを新たに生成したい場合は、FileTime クラスの static メソッド
- FileTime#fromMillis() メソッド
- FileTime#from() メソッド
を使います。 java.io.File のように long 値で簡単に更新時刻の操作ができないのがちょっと面倒な気もするけど・・・ まぁ、サンプル・コードを見ていきましょう:
import java.nio.file.Files import java.nio.file.attribute.BasicFileAttributes import java.nio.file.attribute.FileTime import java.time.ZoneId import java.time.ZonedDateTime // 準備 def src = Files.createTempFile(null, null) // 時刻の取得 println Files.getLastModifiedTime(src) // 「2012-05-25T00:00:00Z」などと表示 // FileTime#toString() がオーバーライドされてるので見やすい出力 // 時刻の更新 def day = Date.parse("yyyy-MM-dd@hh:mm:ss", "1999-12-31@00:00:00") // Groovy! def d = FileTime.fromMillis(day.getTime()) // FileTime#fromMillis() で FileTime オブジェクト取得 Files.setLastModifiedTime(src, d) println Files.getLastModifiedTime(src) // 「1999-12-30T15:00:00Z」と表示(タイムゾーンのため時刻がズレている) // 【追記】 Java8 Date and Time API の Instant オブジェクト関連 // 時刻の取得 def creationTime = Files.readAttributes(src, BasicFileAttributes.class).creationTime() def instant = creationTime.toInstant() // FileTime → Instant def dt1 = ZonedDateTime.ofInstant(instant, ZoneId.of("Asia/Tokyo")) println dt1 //「2012-05-25T09:00:00+09:00[Asia/Tokyo]」などと表示 // 時刻の更新 def dt2 = ZonedDateTime.parse("2015-10-20T00:00+09:00[Asia/Tokyo]") Files.setLastModifiedTime(src, FileTime.from(dt2.toInstant())) // Instant → FileTime println Files.getLastModifiedTime(src) // 「2015-10-19T15:00:00Z」と表示
Java8 から Date and Time API の java.time.Instant オブジェクトに関連するメソッド
- FileTime#from(Instant) (static メソッド) : Instant → FileTime
- FileTime#toInstant() : FileTime → Instant
が追加されたのでサンプルコードに少しコードを追加しました。
ファイル所有者
次はファイル所有者を取得・設定するメソッド。メソッド | 返り値 | 説明 |
---|---|---|
getOwner(Path, LinkOption...) | UserPrincipal | ファイル所有者を取得する |
setOwner(Path, UserPrincipal) | Path | ファイル所有者を設定する |
ファイル所有者は java.nio.file.attribute.UserPrincipal を介して設定します:
package java.nio.file.attribute; public interface UserPrincipal{}
UserPrincipal オブジェクトを新たに生成したい場合は java.nio.file.attribute.UserPrincipalLookupService オブジェクのメソッド
- UserPrincipalLookupService#lookupPrincipalByName(String)
- UserPrincipalLookupService#lookupPrincipalByGroupName(String)
のどちらかを呼び出します。 メソッドを呼び出す UserPrincipalLookupService オブジェクトを取得するには、FileSystem#getUserPrincipalLookupService() メソッドを使いますが、FileSystem オブジェクト自体は FileSystems#getDefault() メソッドを使います:
import java.nio.file.Files import java.nio.file.FileSystems // 準備 def src = ... // getter println Files.getOwner(src) //setter def lookupService = FileSystems.getDefault().getUserPrincipalLookupService() // UserPrincipalLookupService オブジェクトを取得 def admin = lookupService.lookupPrincipalByName("Administrator") // UserPrincipal を取得 Files.setOwner(src, admin) println Files.getOwner(src)
- UserPrincipalLookupService オブジェクトを取得するのは結構マワリクドイですが、定型句として使うしかなさそうです。
POSIX ファイル権限
最後は POSIX ファイル権限の取得・設定。 UNIX 系の OS 用です。メソッド | 返り値 | 説明 |
---|---|---|
getPosixFilePermissions(Path, LinkOption...) | Set |
ファイル所有者を取得する |
setPosixFilePermissions(Path, Set |
Path | ファイル所有者を設定する |
POSIX ファイル権限は java.nio.file.attribute.PosixFilePermission のセット (Set) を介して設定します。 ちなみに
- java.nio.file.attribute.PosixFilePermission ・・・ 列挙型
- java.nio.file.attribute.PosixFilePermissions ・・・ クラス(ユーティリティクラス)
です。 それぞれの型定義は以下のようになってます:
package java.nio.file.attribute; public enum PosixFilePermission{ OWNER_READ, OWNER_WRITE, OWNER_EXECUTE, GROUP_READ, GROUP_WRITE, GROUP_EXECUTE, OTHERS_READ, OTHERS_WRITE, OTHERS_EXECUTE } public final class PosixFilePermissions{ // Set<PosixFilePermission> -> FileAttribute public static FileAttribute<Set<PosixFilePermission>> asFileAttribute(Set<PosixFilePermission> perms); // String -> Set<PosixFilePermission> public static Set<PosixFilePermission> fromString(String perms); // Set<PosixFilePermission> -> String public static String toString(Set<PosixFilePermission> perms): }
- PosixFilePermissions クラスのメソッドの1つ目のメソッドは「これからの「Java I/O」の話をしようwww (3) : Files クラスのメソッド 〜ファイル、ディレクトリの作成〜」で触れたので、以下のサンプルでは省略
- PosixFilePermissions クラスのメソッドの2つ目、3つ目のメソッドに出てきている String オブジェクトは "rwxr-x---" という形式の文字列です。 この形式の文字列と Set<PosixFilePermission> オブジェクトの間の変換を行います
ではサンプル・コード:
import java.nio.file.Files import java.nio.file.attribute.PosixFilePermissions import java.nio.file.attribute.PosixFilePermission import static java.nio.file.attribute.PosixFilePermission.* // PosixFilePermission の定数は static import // 準備 def src = ... // PosixFilePermissions のサンプル assert "rwxr-x---" == PosixFilePermissions.toString( EnumSet.of(OWNER_READ, OWNER_WRITE, OWNER_EXECUTE, GROUP_READ, GROUP_EXECUTE)) // enum 定数のセットは EnumSet#of() で。 try{ // getter println Files.getPosixFilePermissions(src) // setter // enum (PosixFilePermission) で Files.setPosixFilePermissions(src, EnumSet.of( OWNER_READ, OWNER_WRITE, OWNER_EXECUTE, GROUP_READ, GROUP_EXECUTE)) println Files.getPosixFilePermission(src) // 文字列で Files.setPosixFilePermissions(src, PosixFilePermissions.fromString("rwxr-x---")) println Files.getPosixFilePermission(src) }catch(UnsupportedOperationException ex){ ex.printStackTrace() }
- 列挙型 PosixFilePermission の定数(OWNER_READ とか)は static import してます
- 列挙型のセットは EnumSet#of() で作るのが手軽です
- POSIX ファイル権限をサポートしてない場合(Windows とか)、UnsupportedOperationException が投げられます
【追記・修正】
FileTime クラスの Java8 Date and Time API 関連のメソッドに関して少し追記しました。- 作者: 関谷和愛,上原潤二,須江信洋,中野靖治
- 出版社/メーカー: 技術評論社
- 発売日: 2011/07/06
- メディア: 単行本(ソフトカバー)
- 購入: 6人 クリック: 392回
- この商品を含むブログ (155件) を見る