Java NIOチュートリアルファイルシステム

5918 ワード

NIOで2のファイルシステムでは、Pathはすべての操作の基礎です.Pathは正確には、ファイルシステムの位置を表します.ディレクトリ(通常はフォルダ)を表すか、ファイルを表すことができます.
新しいファイルシステムでは、もう一つ言わざるを得ないのがFilesです.それは道具類ですが、この道具類は鶏の血を打ったのと同じように、不思議なほど強いです.以前は、煩雑なコードを書くか、サードパーティのクラスライブラリを呼び出す必要があった機能が、1行だけ必要になりました.
次のコードは、Pathの最も基本的な動作を示しています.Pathを取得します.そして、私たちが得たPathと強力なツールクラスFilesを通じてファイルやディレクトリを作成します.
Path dir0 = Paths.get("c:\\test");//     Path  ;Paths    ,    Path
Files.createDirectory(dir0);//       ;           
Path dir1 = Paths.get("c:\\test\\Hello.java");
Files.createFile(dir1);//     ;           
Path dir2 = Paths.get("c:\\test\\Hello\\World");
Files.createDirectories(dir2);//       ;           

最も基本的な作成機能を示した後、Pathの高度な機能--ディレクトリを巡る
ディレクトリを巡回するには2つの方法があります.1つはDirectoryStreamクラスを介して単層ディレクトリを巡回する方法であり、もう1つはFileVisitorインタフェースを実装することによって再帰されるディレクトリです.
この二つの違いを重点的に強調します.Directory Streamは、指定されたディレクトリの下にあるファイルまたはディレクトリのみを巡回できます.指定されたディレクトリの下にサブディレクトリがある場合、Directory Streamはサブディレクトリの内容を下に巡回しません.FileVisitorインタフェースを実装する方法では、指定されたディレクトリの下にサブディレクトリがある場合、サブディレクトリ内のコンテンツ(深度優先検索と同様)を巡回します.
上のコードはまずDirectory Streamの方法を示します
Path dir3 = Paths.get("c:\\test");
// 1.DirectoryStream       Path Iterable,   dir3           Path  
// 2.       try-with-resources   ,     java1.7       (          ,               )
try (DirectoryStream<Path> stream = Files.newDirectoryStream(dir3,
		"*.java")) {
	for (Path entry : stream) {
		System.out.println(entry.getFileName());
	}
}

もっと強調して新DirectoryStreamの2番目のパラメータ.この形式はglob式であり、*.javaのように「.java」で終わるすべての文字列を表す.
次に、FileVisitorインタフェースを実現する方法について説明します.ここでFilesを用いなければならない静的方法Files.walkFileTree(Path start,FileVisitor<? super Path> visitor)は第一目で複雑で、walkFileTreeの2つのパラメータを見ると善作ではなく、それを実現するには次の4つの方法を実現しなければならない.
  • FileVisitResult postVisitDirectory(T dir, IOException exc)
  • FileVisitResult preVisitDirectory(T dir, BasicFileAttributes attrs)
  • FileVisitResult visitFile(T file, BasicFileAttributes attrs)
  • FileVisitResult visitFileFailed(T file, IOException exc)

  • 幸いjava 1.7デフォルトの実装クラスSimpleFileVisitorが用意されています.これにより、必要な方法を書き換えるだけで、次の例では、ディレクトリの下のすべてのファイルの名前を印刷することができます(フォルダの名前は印刷しません).
    Path dir3 = Paths.get("c:\\test");
    Files.walkFileTree(dir3, new SimpleFileVisitor<Path>() {
    	@Override
    	public FileVisitResult visitFile(Path file,
    			BasicFileAttributes attrs) throws IOException {
    		System.out.println(file.getFileName());
    		return FileVisitResult.CONTINUE;
    	}
    });

    2つの難しいコードを見終わったので、簡単にしましょう.
    ファイルの作成、削除、コピー、移動、名前変更などの操作は、私たちが普段よく使う操作です.以前書きたいなら、本当に工夫したり、第三者のクラスライブラリを直接探したりしなければなりません.しかし今は時代が違って、Filesがあればすべてが糸のように滑らかになった.Filesのドキュメントを見てみましょう.そこにはあなたが夢見ている方法がたくさんあります.ここにはよく使われるものがいくつか展示されています.
    まずファイルやディレクトリを削除する
    Path dir4 = Paths.get("c:\\test\\del");
    Files.delete(dir4);//         ;      ,                  
    Files.deleteIfExists(dir4);//               

    削除は簡単でしょうが、コピーを見てみましょう.
    レプリケーションを考慮する場合は少し多いですが、レプリケーションで主に使用する方法はFiles.copy(Path source,Path target,CopyOption... options)の最初の2つのパラメータがそれぞれ元の位置と目的の位置であり、3番目のパラメータがレプリケーションオプションです.レプリケーションオプションとは、レプリケーション時に様々な状況が発生した場合、どのように処理するかを意味します.CopyOptionも実際には書かせるべきですが、javaにはStandardCopyOption.REPLACE_EXISTINGという3つの方法が内蔵されています.目的のパスに同名のファイルがあればStandardCopyOption.ATOMIC_MOVEを置き換えます.失敗した場合はStandardCopyOption.COPY_ATTRIBUTESをロールバックします.ソースファイルのファイル属性を新しいファイルにコピーします(readAttributesなどの方法でファイル属性を読み取ることができます).
    例をあげましょう
    Path source = Paths.get("c:\\test\\Hello.java");
    Path target = Paths.get("c:\\test\\Hello\\World\\Hello.java");
    Files.copy(source, target, StandardCopyOption.REPLACE_EXISTING);

    また、ファイルの移動については、基本的にコピーと同じで、主にFiles.move(Path source,Path target,CopyOption... options)と同じ方法で使用されていますが、コピーオプションも必要ですが、実際にファイルの名前を変更するためにも使用されています.以下の例では、この点を示しています.
    Path source = Paths.get("c:\\test\\Hello\\World\\Hello.java");
    Path target = Paths.get("c:\\test\\Hello\\World\\He.java");
    Files.move(source, target, StandardCopyOption.REPLACE_EXISTING);

    次に紹介するのは私の大好きな内容で、2つの方法List<String> Files.readAllLines(Path path) Files.write(Path path,Iterable<? extends CharSequence> lines,OpenOption... options)が一目瞭然かどうかを見せます.これが書類の行読みと行書きで、本当に便利です.java 1.7以前、guavaでこれらの方法を見たことがあります.guavaのioを使うのは、sourceとsinkのためではなく、これらの方法のためです.この2つの方法の出現はjavaの新しい態度を反映している.それは諫言、虚心である.優れたネーミング、便利なツール類は、以前java公式に欠けていたもので、新しいTimeパッケージでもlamda式でもCoinプロジェクトでも、コミュニティに優れたコミュニティ資源を学び、吸収し、開発者の夢を現実に変え、開発者を便利にすることです.遠くまで話してすみません.それでは直接コードをつけます
    Path source = Paths.get("c:\\test\\Hello\\World\\Ab.java");
    Path target = Paths.get("c:\\test\\Hello\\World\\He.java");
    		
    //                 , StandardCharsets           
    List<String> list = Files.readAllLines(source, StandardCharsets.UTF_8);
    for (String s : list) {
    	System.out.println(s);
    }
    // StandardOpenOption                 
    Files.write(target, list, StandardCharsets.UTF_8,StandardOpenOption.WRITE);

    NIO全体2の新しいファイルシステムの主な内容は、基本的にこれだけです最后に私达が来たのは少しハイエンドのファイルシステムの监视です;主に使う类はjava.nio.file.WatchServiceで、この类は登录した后で、ずっとファイルあるいはディレクトリの変化を监视して、もし相応の変化が発生するならば、1つの事件に戻ります.これは多くの地方ですべて役に立ちます、その上この类の性能は悪くありません
    try (WatchService watcher = FileSystems.getDefault().newWatchService()) {
    	Path dir = Paths.get("c:\\test");
    	WatchKey key = dir.register(watcher,
    			StandardWatchEventKinds.ENTRY_DELETE);
    	for (;;) {
    		key = watcher.take();
    		for (WatchEvent<?> event : key.pollEvents()) {
    			System.out.println(event.kind());
    		}
    		boolean valid = key.reset();
    		if (!valid) {
    			break;
    		}
    	}
    }

    NIOについて2の中の新しいファイルシステムはこんなにたくさん話して、何か問題があったら討論を歓迎して、もし何か間違いがあれば、教えてください(急いで教えてください、私はよく直して、遅くなって他の人を遅らせます)