NIO2

6973 ワード

NIO2
I/O発展履歴
Java1.0-1.3
Javaの初期バージョンでは、完全なI/Oサポートがなく、開発中に以下の問題を解決する必要があります:1)データバッファやNIOのチャネル概念がなく、プログラマが最下位の詳細を処理する必要があります.2)I/Oはブロックされている.3)正規表現がサポートされておらず,データ処理が困難である.
Java 1.4 NIO導入
Java 1.4フェーズでは、非ブロックI/Oのサポートを開始します.開発者がより高速で信頼性の高いI/Oソリューションを提供するのを支援します.主に2回導入:1)Java 1.4に非ブロックI/Oを導入した.2)Java 7で非ブロックI/Oを修正する.しかし,1)異なるプラットフォームにおけるファイル名の処理が一致しないという限界がある.2)ファイル属性パターンが統一されていない.3)目次をたどることが困難である.4)プラットフォーム/オペレーティングシステムの特徴を使用できない.5)ファイルシステムの非ブロック動作はサポートされていない.
I/O – NIO.2
NIOの限界を解決するために、同時に現代のハードウェアとソフトウェアのI/Oの新しい規範をサポートするために.NIO.2 APIを導入した.主な特性は、1)ファイル属性を一括的に取得できるファイルシステムインタフェース、特定のファイルシステムに関連するAPIの取り消し、標準ファイルシステムの実装を導入するためのサービスプロバイダインタフェースである.2)ソケットとファイルの両方で非同期I/O操作が可能なAPIを導入する.3)JSR-51で定義したソケット-チャネル機能を完成する.
Path
NIO.2のファイルI/Oでは、Pathは把握しなければならない重要なクラスの一つです.Pathは抽象的な構造であり,Pathを作成して処理する際に対応する物理的位置をすぐにバインドする必要はない.Pathは、通常、ファイルシステム内の位置、例えば、c://path....などのパスアドレスを表す.
Pathは従来のファイルシステムに限らずzipやjarのようなファイルシステムを表すこともできる.
Pathの作成
以下の方法では、Pathクラスを簡単に作成できます.
@Test
public void test1() {
    Path path = Paths.get("D:\\path");
    Path path1 = Paths.get("D:", "path");
    Path path2 = FileSystems.getDefault().getPath("D:\\path");
}

Pathから情報を取得
これは簡単にPathの中の一部の方法を羅列するだけで、詳しくはAPIを見ることができます.
@Test
public void test2() {
    Path path = Paths.get("D:\\path");
    System.out.println("   :" + path.getFileName());//        
    System.out.println("          :" + path.getNameCount());//      
    System.out.println("     :" + path.getParent());//   
    System.out.println("ROOT:" + path.getRoot());//   
}

PathとFileの変換
PathはFileの代わりに使用できますが、システムに残されたコードが維持されることは避けられません.すべてのAPIはPathとFileの変換を提供します.
@Test
public void test2() {
    Path path = Paths.get("D:\\path");
    File file = path.toFile();
    Path path1 = file.toPath();
}

ディレクトリとディレクトリツリーの操作
遍歴ディレクトリはJava 7が注目を集めている新しい特性です.新しく追加されたjava.nio.file.DirectoryStreamインタフェースとその実装クラスシステムには、1)ディレクトリ内のサブアイテムをループし、ディレクトリ内のファイルを検索するなど、多くの機能があります.2)ディレクトリサブアイテムとMIMEベースのコンテンツ検出(例えばtext/xml)をglob式で一致させる.3)walkFileTreeメソッドは再帰的な移動/複製と削除を実現する.
ディレクトリ内のファイルの検索
たとえば、フォルダに.properties接尾辞ファイルを羅列します.以前は、ファイルの接尾辞名を巡回して比較する必要がありました.ファイルはglob式でフィルタリングされ、Googleの具体的なチュートリアルを参照してください.
@Test
public void test2() {
    Path path = Paths.get("D:\\path");
    try (
        DirectoryStream paths = Files.newDirectoryStream(path, "*.properties");
    ) {
        for (Path p : paths ) {
            System.out.println("file name = " + p.getFileName());
        }
    } catch (IOException e) {

    }
}

ディレクトリツリーを巡回
Java 7は、ディレクトリツリー全体(サブディレクトリも巡回)の巡回操作をサポートします.これにより、サブディレクトリを簡単に検索して実行できます.Files.walkFileTree(Path startingDir, FileVisitor Super Path> vistor);最も重要な方法です.FileVisitorは4つのメソッド(Java 8)を実装する必要がありますが、APIにはデフォルトの実装クラスSimpleFileVisitorが用意されています.
@Test
public void test3() throws IOException {
    Path path = Paths.get("D:\\path");
    Files.walkFileTree(path, new FindXMLVisitor());
}

class FindXMLVisitor extends SimpleFileVisitor {
    @Override
    public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
        if (file.toString().endsWith(".xml")) {
            System.out.println(file.getFileName());
        }
        return FileVisitResult.CONTINUE;
    }
}

NIO.2のファイルシステムI/O
NIO.2ではファイルシステムの移動ファイル/ファイル属性の変更などが改善され、サポートされています.主にFilesクラスから提供されます.
ファイルの作成と削除
@Test
public void test4() throws IOException {
    Path path = Paths.get("D:\\path\\create.xml");
    //Files.createFile(path);
    Files.delete(path);
}

ファイルのコピーと移動
@Test
public void test4() throws IOException {
    Path source = Paths.get("D:\\path\\123.txt");
    Path target = Paths.get("D:\\path\\456.txt");
    //              ,       ,          
    Files.copy(source, target, StandardCopyOption.REPLACE_EXISTING);
}
@Test
public void test4() throws IOException {
    Path source = Paths.get("D:\\path\\123.txt");
    Path target = Paths.get("D:\\path\\backup\\123.txt");
    //              ,       ,          
    Files.move(source, target, StandardCopyOption.REPLACE_EXISTING);
}

データの高速読み書き
Java 7では、バッファ付きリーダおよびライタまたは入出力ストリーム操作ファイルを直接使用できます.
@Test
public void test5() {
    Path readers = Paths.get("D:\\path\\123.txt");
    Path writes = Paths.get("D:\\path\\456.txt");
    try (BufferedReader reader = Files.newBufferedReader(readers,StandardCharsets.UTF_8);
        BufferedWriter writer = Files.newBufferedWriter(writes, StandardCharsets.UTF_8)) {
        //  
        String line;
        while ((line = reader.readLine()) != null) {
            System.out.println(line);
        }
        //  
        writer.write("write");
    } catch (IOException e) {
        e.printStackTrace();
    }
}

一度にすべてを読みます.ファイルの内容が大きい場合は、メモリが漏れやすいので、このように読まないことをお勧めします.
@Test
public void test5() {
    Path readers = Paths.get("D:\\path\\123.txt");
    try {
        List lines = Files.readAllLines(readers,StandardCharsets.UTF_8);
        for (String line : lines) {
            System.out.println(line);
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
}

非同期I/O操作
非同期IOは、実際には読み書き操作を行う際に他の操作処理を許可するだけである.
将来式
将来式はjava.util.concurrent.Futureインタフェースのみを使用し、そのインタフェースのgetメソッドを使用した後、処理が完了したらすぐにデータを返し、なければブロックします.
@Test
public void test6() throws IOException, ExecutionException, InterruptedException {
    Path readers = Paths.get("D:\\path\\123.txt");
    //      
    AsynchronousFileChannel channel = AsynchronousFileChannel.open(readers);
    ByteBuffer buffer = ByteBuffer.allocate(100_000);//  100 000  
    Future result = channel.read(buffer, 0);//  
    //      
    System.out.println("      ");
    Integer integer = result.get();//    ,           ,         
}

コールバック方式
コールバック式は、処理が完了した後にコールバック関数を実行する方法で通知されます.
@Test
public void test7() throws IOException {
    Path readers = Paths.get("D:\\path\\123.txt");
    //      
    AsynchronousFileChannel channel = AsynchronousFileChannel.open(readers);
    ByteBuffer buffer = ByteBuffer.allocate(100_000);//  100 000  
    channel.read(buffer, 0, buffer, new CompletionHandler() {
        @Override
        public void completed(Integer result, ByteBuffer attachment) {
            System.out.println("            ");
        }

        @Override
        public void failed(Throwable exc, ByteBuffer attachment) {
            System.out.println("          ");
        }
    });
}