NIOの(1)研究と応用

NIOさんのプロフィール

  • JavaのNIO(新IO)IO APIが導入の最初から新しいJava 1.4バージョンでは、標準のJava IOのAPIを置き換えることができます。NIO IO本来の目的と同じ効果を有するが、IOチャネル動作に基づいて使用の完全に異なるモード、配向バッファサポートNIO、。NIOファイルは読み取りと書き込みの操作がより効率的な方法になります。

NIOとIOの違い
ここに画像を挿入説明

バッファ(バッファ)のデータアクセス

  • JavaのNIO内のデータへのアクセスを担当。バッファが配列です。異なるデータ型のデータを格納します
  • (ブール値を除く)は、異なるデータタイプ、バッファの対応するタイプ提供する:
    ByteBufferの
    CharBufferの
    ShortBuffer
    IntBuffer
    LongBuffer
    FloatBuffer
    のDoubleBufferを

バッファ管理スタイルの上にほぼ同じである、(割り当てることにより、バッファを取得します)

  • 2つのコア・メソッドのデータバッファへのアクセス

       データをバッファに格納されています)(置く
       バッファにデータを取得します。get()

  • 4つのコア属性をバッファリング

       ①、容量:容量は、データを格納するバッファの最大容量を表します。宣言は、変更することはできませんしたら

       ②、制限:制限は、データのバッファサイズを操作することができ表します。(制限データを読み取ることができません)

       ③、位置:位置は、バッファ内の位置が動作している表します。

       ④、マーク:現在の位置の記録位置を示すマーク。()マークのリセット位置に戻ることができます

       0 <=位置<=リミット<=容量

  • バッファの基本的な性質
    ここに画像を挿入説明
  • バッファーA一般的な方法の
    ここに画像を挿入説明
    コードは以下の通りであります:
@Test
public void test01(){
    String str = "abcde";
    //1,分配一个指定大小的缓存区
    ByteBuffer buffer = ByteBuffer.allocate(1024);
    System.out.println(buffer.position());//0
    System.out.println(buffer.limit());//1024
    System.out.println(buffer.capacity());//1024
    //2,利用put()存入数据到缓冲区中
    buffer.put(str.getBytes());
    //3,利用flip()读取数据模式
    buffer.flip();
    //4,利用get()读取缓冲区中的数据
    byte[] dst = new byte[buffer.limit()];
    buffer.get(dst);
    System.out.println(new String(dst, 0, dst.length));
    //5,rewid():可重复度
    buffer.rewind();
    //6,clear():清空缓冲区,但是缓冲区中的数据依然存在,但处于“被遗忘”的状态,被遗忘--里面的界限,位置都变成了最初状态,不能正确读取数据
    buffer.clear();
}
  • 直接および非直接バッファバッファ

       ①、非ダイレクトバッファー:()メソッドは、JVM内のバッファメモリに基づいて、割り当てることによってバッファを割り当てます。図は、次の
ここに画像を挿入説明
       ②、ダイレクトバッファー:直接allocateDirectバッファによって割り当てられたの()メソッドは、バッファは、物理メモリ内に確立され、効率を向上させることができます。図は次のとおりです。
ここに画像を挿入説明

原則との捕捉チャネル(チャネル)

  • チャンネル(チャンネル):ソースノードと宛先ノードとを接続します。でjavaNIOのデータバッファの送信を担当します。チャネルデータは、それ自体に記憶され、したがって緩衝液で送信される必要がされていません
  • 次のようにチャネルインターフェイスのために提供される最も重要な実装クラスなどのJava:

       ①、のFileChannel:、読み取り、書き込み、およびファイルマッピングを操作するため。

       ②、のDatagramChannel:UDP経由の書き込みデータパスネットワーク。

       ③、のSocketChannel:TCP経由の書き込みデータネットワーク。

       ④、のServerSocketChannel:あなたは、新しい着信TCP接続をリッスンになりますそれぞれの新しい着信接続のためのSocketChannelを作成することができます。

  • 買収チャンネル

    ①、Javaのクラスパス上さらに、getChannel()メソッドを提供します。次のとおりです。

       本地IO:
        FileInputStreamの
        たFileOutputStream
        のRandomAccessFile

       ネットワークIO:
        DatagramSocketの
        ソケット
        ServerSocketを

    ②、JDK1.7 NIO.2に)(オープンチャネルごとに静的メソッドを提供します

    ③、JDK1.7でのツールのnewByteChannelファイルNIO.2()

  • チャンネル(非ダイレクトバッファ)ファイルを使用して完成されるコピー。コードは以下の通りです
@Test
public void test01() throws Exception{
    FileInputStream fis = new FileInputStream("1.jpg");
    FileOutputStream fos = new FileOutputStream("2.jpg");

    //1,获取通道
    FileChannel inChannel = fis.getChannel();
    FileChannel outChannel = fos.getChannel();

    //2,分配指定大小的缓冲区
    ByteBuffer buffer = ByteBuffer.allocate(1024);

    //3,将通道中的数据存入缓冲区中
    while (inChannel.read(buffer) != -1){
        buffer.flip();//切换读取数据库模式
        //4,将缓冲区中的数据写入通道中
        outChannel.write(buffer);
        buffer.clear();//清空缓冲区
    }

    outChannel.close();
    inChannel.close();
    fis.close();
    fos.close();
}
  • ダイレクトバッファに完全なコピー(メモリマップドファイル)ファイルを使用してください。コードは以下の通りであります:
    @Test
    public void test02() throws Exception {
        FileChannel inChannel = FileChannel.open(Paths.get("1.jpg"), StandardOpenOption.READ);
        FileChannel outChannel = FileChannel.open(Paths.get("3.jpg"),StandardOpenOption.WRITE,StandardOpenOption.READ,StandardOpenOption.CREATE);

        //内存映射文件
        MappedByteBuffer inMapped = inChannel.map(FileChannel.MapMode.READ_ONLY, 0, inChannel.size());
        MappedByteBuffer outMapped = outChannel.map(FileChannel.MapMode.READ_WRITE,0,inChannel.size());

        //直接对缓冲区进行数据的读写操作
        byte[] bytes = new byte[inMapped.limit()];
        inMapped.get(bytes);
        outMapped.put(bytes);

        inChannel.close();
        outChannel.close();
    }
  • チャンネル間のデータ転送。コードは以下の通りであります:
    //(直接缓冲区)
    @Test
    public void test03() throws Exception {
        FileChannel inChannel = FileChannel.open(Paths.get("D://1.mkv"), StandardOpenOption.READ);
        FileChannel outChannel = FileChannel.open(Paths.get("D://2.mkv"),StandardOpenOption.WRITE,StandardOpenOption.READ,StandardOpenOption.CREATE);

//        inChannel.transferTo(0,inChannel.size(),outChannel);
        outChannel.transferFrom(inChannel,0, inChannel.size());

        inChannel.close();
        outChannel.close();
    }

分散(散布)が集合(収集)の書き込みを読み込みます

  • 分散液は、(散乱読み込み)をリードデータを意味するが、チャネルから読み取るバッファの複数に「分散」。
    注意:バッファの順序は、データは、チャネルバッファ充填から順次読み出されます。
    ここに画像を挿入説明

  • ギャザーライト(ギャザリングが書き込み)チャネルに「集め」バッファの複数のデータを指します。
    注意:バッファの順序は、データが限界位置とチャネルとの間に書き込まれます。コードは以下の通りであります:

//分散和聚集
@Test
public void test04() throws Exception {
    RandomAccessFile raf1 = new RandomAccessFile("1.txt","rw");
    //1,获取通道
    FileChannel channel = raf1.getChannel();
    //2,分配指定大小的缓冲区
    ByteBuffer buffer1 = ByteBuffer.allocate(100);
    ByteBuffer buffer2 = ByteBuffer.allocate(1024);
    //3,分散读取
    ByteBuffer[] buffers = {buffer1,buffer2};
    channel.read(buffers);
    for (ByteBuffer byteBuffer : buffers){
        byteBuffer.flip();
    }
    System.out.println(new String(buffers[0].array(),0, buffers[0].limit()));
    System.out.println(new String(buffers[1].array(), 0, buffers[1].limit()));

    //聚集写入
    RandomAccessFile raf2 = new RandomAccessFile("2.txt","rw");
    FileChannel channel2 = raf2.getChannel();
    channel2.write(buffers);
}

文字セット:文字セット

  • エンコード:文字列- >バイト配列
  • デコード:バイト配列- >文字列

エンコーディングと文字セットのサポートをデコードします。次のようにコードがあります

//编码和解码支持的字符集
@Test
public void test06() throws Exception {
    Map<String, Charset> map = Charset.availableCharsets();
    Set<Map.Entry<String, Charset>> set = map.entrySet();
    for (Map.Entry<String, Charset> entry : set) {
        System.out.println(entry.getKey()+ "=" + entry.getValue());
    }
}

エンコードとデコード。次のようにコードがあります

//编码和解码
@Test
public void test05() throws Exception {
    Charset gbk = Charset.forName("GBK");
    //获取编码器
    CharsetEncoder encoder = gbk.newEncoder();
    //获取解码器
    CharsetDecoder decoder = gbk.newDecoder();
    CharBuffer charBuffer = CharBuffer.allocate(1024);
    charBuffer.put("Tommey周");
    charBuffer.flip();
    //编码
    ByteBuffer encodeBuffer = encoder.encode(charBuffer);
    for (int i = 0; i < 8; i++) {
        System.out.println(encodeBuffer.get());
    }
    //解码
    encodeBuffer.flip();
    CharBuffer decodeBuffer = decoder.decode(encodeBuffer);
    System.out.println(decodeBuffer.toString());
    //以GBK编码UTF-8解码 出现乱码
    Charset utf8 = Charset.forName("UTF-8");
    encodeBuffer.flip();
    CharBuffer decodeBuffer1 = utf8.decode(encodeBuffer);
    System.out.println(decodeBuffer1.toString());
}

次の章、学習と応用(2)NIOさん

公開された67元の記事 ウォン称賛19 ビュー9860

おすすめ

転載: blog.csdn.net/qq_41530004/article/details/104683973