順次、選択、そして繰り返し

プログラミングのことやITのこと、たまに演劇のことも書きます。

NIO.2について

NIO.2(New I/O 2)とはJava7から登場した新しいファイルシステムインターフェースのこと。

Java6まではファイルの属性の取得・設定やディレクトリの監視をすることができなかったため、それらの処理ができるインターフェースをNIO.2として用意された。

NIO.2の関連パッケージ


java.nio.file

ファイル、ファイル属性及びファイルシステムにアクセスするためのインターフェースとクラスが提供されている。

Class or Interface 名前 説明
Interface Path ファイルシステム内のファイルを特定するために使用するシステムに依存するファイルパスを表す
Class Paths パス文字列パス文字列またはURIを変換してPathオブジェクトを返すstaticメソッドを提供
Class FileSystems ファイルシステム用のファクトリクラス。
Class FileSystem ファイルシステムへのインタフェースを提供し、ファイルシステム内のファイルやその他のオブジェクトにアクセスするための手段を提供する

Pathインタフェース

Paths.get()の挙動
//Paths.get()では環境に応じたパスを持ったPathオブジェクトを返す
//path1ではファイルセパレータが"/"から"\"に変換されている
Path path1 = Paths.get("test/hoge.txt");
Path path2 = Paths.get("F:\\GitRepository");
Path path3 = Paths.get("F:","GitRepository");

System.out.println("path1:" + path1);
System.out.println("path2:" + path2);
System.out.println("path3:" + path3);
Paths.get()実行結果
path1:test\hoge.txt
path2:F:\GitRepository
path3:F:\GitRepository
Pathインタフェースの主なメソッド
Path path4 = Paths.get("F:\\GitRepository\\hoge.txt");

//パスの文字列表現を返す
System.out.println("toString:" + path4.toString());

//名前要素シーケンスの最後を返す
System.out.println("getFileName:" + path4.getFileName());

//指定したインデックスに対するパス要素を返す。0番目はルートに最も近い要素
System.out.println("getName(0):" + path4.getName(0));

//パス内の要素数を返す
System.out.println("getNameCount:" + path4.getNameCount());

//パスのルートを返す
System.out.println("getRoot:" + path4.getRoot());

//親ディレクトリのパスを返す
System.out.println("getParent:" + path4.getParent());

//開始インデックスから終了インデックス-1の要素を取得
System.out.println("subpath0-2:" + path4.subpath(0, 2));
System.out.println("subpath1-2:" + path4.subpath(1, 2));

Path path5 = Paths.get("./hoge.txt");

//冗長な名前要素を削除したパスを返す
System.out.println("normalize:" + path5.normalize());

//パスを表すURIを返す
System.out.println("toUri:" + path5.toUri());

//絶対パスか判定絶対パスの場合はTrue
System.out.println("isAbsolute:" + path5.isAbsolute());

//絶対パスを返す
System.out.println("toAbsolutePath:" + path5.toAbsolutePath());

//既存ファイルの実際のパスを返す
try {

    //既存ファイルの実際のパスを返す
    System.out.println("toRealPath:" + path5.toRealPath());
} catch (IOException e) {

    e.printStackTrace();
}

//パスの結合(引数が絶対パスの場合は引数の値が返ってくる)
Path path6 = Paths.get("hogehoge");
Path path7 = Paths.get("test");
System.out.println("resolve:" + path6.resolve(path7));

//指定されたパス間の相対パスを返す
System.out.println("relativize:" + path6.relativize(path7));
実行結果
toString:F:\GitRepository\hoge.txt
getFileName:hoge.txt
getName(0):GitRepository
getNameCount:2
getRoot:F:\
getParent:F:\GitRepository
subpath0-2:GitRepository\hoge.txt
subpath1-2:hoge.txt
normalize:hoge.txt
toUri:file:///F:/GitRepository/AppRepository/workspace/JavaWork/./hoge.txt
isAbsolute:false
toAbsolutePath:F:\GitRepository\AppRepository\workspace\JavaWork\.\hoge.txt
toRealPath:F:\GitRepository\AppRepository\workspace\JavaWork\hoge.txt
resolve:hogehoge\test
relativize:..\test

Filesクラス

ファイル、ディレクトリなどを操作するクラス staticメソッドだけで構成されている

Filesクラスの主なメソッド
Path path1 = Paths.get("hogeDir");
Path path2 = Paths.get("F:\\GitRepository\\AppRepository\\workspace\\JavaWork\\hogeDir");
Path path3 = Paths.get("hoge.txt");

//ファイルの存在確認
System.out.println("exists:" + Files.exists(path1));

try {
    //2つのパスが同じファイルを検出するかテストする
    System.out.println("isSameFile:" + Files.isSameFile(path1, path2));
} catch (IOException e) {

    e.printStackTrace();
}

//このパスがディレクトリかテストする
System.out.println("isDirectory:" + Files.isDirectory(path1));

//通常ファイルかテストする
System.out.println("isRegularFile:" + Files.isRegularFile(path1));

//読み取り可能かテストする
System.out.println("isReadable:" + Files.isReadable(path3));

//実行可能かテストする
System.out.println("isExecutable:" + Files.isExecutable(path2));

Path path4 = Paths.get("hogeDir2");

try {
    //ディレクトリの作成
    Files.createDirectory(path4);

    //ディレクトリの削除
    Files.delete(path4);

    //ディレクトリが存在した場合は削除する
    System.out.println("deleteExists:" + Files.deleteIfExists(path4));

} catch (IOException e) {

    e.printStackTrace();
}

Path path5 = Paths.get("hoge2.txt");
Path path6 = Paths.get("hoge2copy.txt");

try {

    //コピーする
    Files.copy(path5, path6, StandardCopyOption.REPLACE_EXISTING);

    //移動またはリネームする
    Files.move(path6, path5, StandardCopyOption.REPLACE_EXISTING);


    //ファイルデータの読み込み
    List<String> list = Files.readAllLines(path3);

    for(String str : list) {
        System.out.println("読み込み行:" + str);
    }


} catch (IOException e) {

    e.printStackTrace();
}
実行結果
exists:true
isSameFile:true
isDirectory:true
isRegularFile:false
isReadable:true
isExecutable:true
deleteExists:false
読み込み行:ほげほげほげ
読み込み行:ホゲホゲホゲ

java.nio.file.attribute

ファイル及びファイルシステム属性にアクセスするためのインターフェースとクラスが提供されている

Class or Interface 名前 説明
Class FileTime ファイルのタイムスタンプ属性の値を表す
Interface FileAttribute 新しいファイル・ディレクトリを作成するときに自動的に設定できるファイル属性を表すオブジェクト
Interface BasicFileAttributes すべてのファイルシステム実装で必要となる基本的な属性を表すオブジェクト
Interface DosFileAttributes DOS属性をサポートするファイルシステムで使用される属性が追加されている
Interface PosixFileAttributes POSIX標準ファミリをサポートするファイルシステムで使用される属性が追加されている
Files.geAttribute()の挙動
Path path1 = Paths.get("hoge.txt");

try {

    //作成日
    Object obj1 = Files.getAttribute(path1, "creationTime");

    //最終更新日
    Object obj2 = Files.getAttribute(path1, "lastModifiedTime");

    //サイズ
    Object obj3 = Files.getAttribute(path1, "size");

    System.out.println("creationTime:" + obj1);
    System.out.println("lastModifiedTime:" + obj2);
    System.out.println("size:" + obj3);

} catch (IOException e) {
    
    e.printStackTrace();
}
Files.geAttribute()実行結果
creationTime:2017-07-26T12:38:49.578851Z
lastModifiedTime:2017-07-26T14:55:17.263971Z
size:38
BasicFileAttributesの挙動
Path path1 = Paths.get("hoge.txt");

try {

    //BasicFileAttributesでメタデータを取得するパターン
    BasicFileAttributes attr = Files.readAttributes(path1, BasicFileAttributes.class);

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


} catch (IOException e) {
    
    e.printStackTrace();
}
BasicFileAttributes実行結果
creationTime:2017-07-26T12:38:49.578851Z
lastModifiedTime:2017-07-26T14:55:17.263971Z
size:38
DosFileAttributesの挙動
Path path1 = Paths.get("hoge.txt");

try {

    //DosFileAttributesでメタデータを取得するパターン
    DosFileAttributes dosAttr = Files.readAttributes(path1, DosFileAttributes.class);

    //アーカイブ属性の値を返す
    System.out.println("isArchive:" + dosAttr.isArchive());

    //隠し属性の値を返す
    System.out.println("isHidden:" + dosAttr.isHidden());

    //読み取り専用属性の値を返す
    System.out.println("isReadOnly:" + dosAttr.isReadOnly());

    //システムの属性の値を返す
    System.out.println("isSystem:" + dosAttr.isSystem());


} catch (IOException e) {
    
    e.printStackTrace();
}
DosFileAttributes実行結果
isArchive:true
isHidden:false
isReadOnly:false
isSystem:false

ディレクトリアクセス関連メソッドの挙動

ディレクトリ・ファイルの配置状態

f:id:sndstudy:20170727234940p:plain

FileSystem fs = FileSystems.getDefault();

//ルートディレクトリを取得する
Iterable<Path> dirs = fs.getRootDirectories();

for(Path name: dirs) {

    System.out.println("RootDir:" + name);

}

Path path1 = Paths.get("hogeDir");

try {

    System.out.println();

    //ディレクトリ内を探索する(サブディレクトリ含む)
    Files.walk(path1).forEach(System.out::println);

    System.out.println();

    //ディレクトリ内を探索する(サブディレクトリは含まない)
    Files.list(path1).forEach(System.out::println);

} catch (IOException e) {

    e.printStackTrace();
}

try {

    System.out.println();

    //パスに対して条件を指定して合ったパスのみで構成されるストリームを返す
    Files.find(path1, 2, (path, attr) -> path.toString().startsWith("hogeDir\\hogehoge1")).forEach(System.out::println);;

} catch (IOException e) {
    e.printStackTrace();
}

Path path2 = Paths.get("hoge.txt");

try {

    //ファイル内のすべての行を読み取る
    System.out.println("line():" + Files.lines(path2).map(word -> word.length()).collect(Collectors.toList()));
} catch (IOException e) {
    e.printStackTrace();
}
ディレクトリアクセス関連メソッドの実行結果
RootDir:C:\
RootDir:D:\
RootDir:E:\
RootDir:F:\

hogeDir
hogeDir\hogehoge1.txt
hogeDir\hogehoge2.txt
hogeDir\hogehoge3.txt
hogeDir\hogehogeDir
hogeDir\hogehogeDir\hogehoge4.txt

hogeDir\hogehoge1.txt
hogeDir\hogehoge2.txt
hogeDir\hogehoge3.txt
hogeDir\hogehogeDir

hogeDir\hogehoge1.txt
line():[6, 6]