二、Javaプログラミングの基礎NIO(ダイレクトおよび非ダイレクトバッファはバッファ)

I.背景

1.以前のブログに着手、私たちは今日NIOプログラミングの下で勉強を続け、ADOは、今日要約し始めました。:特定の記事を参照することができますhttps://blog.csdn.net/chenmingxu438521/article/details/103967066

第二に、バッファでバッファリング直接および間接の区別

1.非ダイレクトバッファー:JVM内のバッファメモリに基づいて割り当てることによってバッファを割り当てる()メソッド、

 2.直接緩衝液:()直接allocateDirectによってバッファを割り当てる方法は、バッファは、物理メモリ内に確立されます。効率を向上させることができます

3.分析します

3.1。バイトバッファは、直接又は非直接です。直接バイトバッファ場合は、Java仮想マシンは、このバッファに直接ネイティブのI / O操作を実行するために最大限の努力を行います。、であることを基本的なオペレーティングシステム、ネイティブI / O操作(またはそれ以降)への各呼び出しの前に、仮想マシンは、中間バッファから中間バッファ(またはコピーコンテンツにバッファの内容をコピー回避しよう)。

3.2 IOデバイス(例えば:ファイル、ソケット)接続をオープンチャネルを表します。NIOシステム必要に応じて、データを受信するためのバッファIO装置と手段を接続するためのチャネルを取得する必要があります。バッファは、次いで、データ処理を動作させます。チャネルは、ストレージの責任バッファの輸送を担当しています。いるjava.nio.channelsパッケージで定義されたパッセージ。チャネルは、接続IOのソースとターゲットのオープンを表します。伝統的に類似チャンネル「の流れ。」チャネル自体が、直接チャンネルのみ相互作用バッファーとすることができ、データにアクセスすることはできません。

4.コード

@Test
	// 使用直接缓冲区完成文件的复制(內存映射文件)
	public void test2() throws IOException {
		FileChannel inChannel = FileChannel.open(Paths.get("1.png"), StandardOpenOption.READ);
		FileChannel outChannel = FileChannel.open(Paths.get("2.png"), StandardOpenOption.READ, StandardOpenOption.WRITE,
				StandardOpenOption.CREATE);
		// 映射文件
		MappedByteBuffer inMapperBuff = inChannel.map(MapMode.READ_ONLY, 0, inChannel.size());
		MappedByteBuffer outMapperBuff = outChannel.map(MapMode.READ_WRITE, 0, inChannel.size());
		// 直接对缓冲区进行数据读写操作
		byte[] dst = new byte[inMapperBuff.limit()];
		inMapperBuff.get(dst);
		outMapperBuff.put(dst);
		outChannel.close();
		inChannel.close();
	}

	@Test
	// 1.利用通道完成文件复制(非直接缓冲区)
	public void test1() throws IOException {
		FileInputStream fis = new FileInputStream("1.png");
		FileOutputStream fos = new FileOutputStream("2.png");
		// ①获取到通道
		FileChannel inChannel = fis.getChannel();
		FileChannel outChannel = fos.getChannel();

		// ②分配指定大小的缓冲区
		ByteBuffer buf = ByteBuffer.allocate(1024);
		while (inChannel.read(buf) != -1) {
			buf.flip();// 切换到读取模式
			outChannel.write(buf);
			buf.clear();// 清空缓冲区
		}
		// 关闭连接
		outChannel.close();
		inChannel.close();
		fos.close();
		fis.close();
	}
直接缓冲区与非直接缓冲耗时计算
	@Test
	// 使用直接缓冲区完成文件的复制(內存映射文件) //428、357
	public void test2() throws IOException {
		long startTime = System.currentTimeMillis();
		FileChannel inChannel = FileChannel.open(Paths.get("f://1.mp4"), StandardOpenOption.READ);
		FileChannel outChannel = FileChannel.open(Paths.get("f://2.mp4"), StandardOpenOption.READ, StandardOpenOption.WRITE,
				StandardOpenOption.CREATE);
		// 映射文件
		MappedByteBuffer inMapperBuff = inChannel.map(MapMode.READ_ONLY, 0, inChannel.size());
		MappedByteBuffer outMapperBuff = outChannel.map(MapMode.READ_WRITE, 0, inChannel.size());
		// 直接对缓冲区进行数据读写操作
		byte[] dst = new byte[inMapperBuff.limit()];
		inMapperBuff.get(dst);
		outMapperBuff.put(dst);
		outChannel.close();
		inChannel.close();
		long endTime = System.currentTimeMillis();
		System.out.println("内存映射文件耗时:"+(endTime-startTime));
	}
	@Test
	// 1.利用通道完成文件复制(非直接缓冲区)
	public void test1() throws IOException {  //11953 、3207、3337
		long startTime = System.currentTimeMillis();
		FileInputStream fis = new FileInputStream("f://1.mp4");
		FileOutputStream fos = new FileOutputStream("f://2.mp4");
		// ①获取到通道
		FileChannel inChannel = fis.getChannel();
		FileChannel outChannel = fos.getChannel();

		// ②分配指定大小的缓冲区
		ByteBuffer buf = ByteBuffer.allocate(1024);
		while (inChannel.read(buf) != -1) {
			buf.flip();// 切换到读取模式
			outChannel.write(buf);
			buf.clear();// 清空缓冲区
		}
		// 关闭连接
		outChannel.close();
		inChannel.close();
		fos.close();
		fis.close();
		long endTime = System.currentTimeMillis();
		System.out.println("非缓冲区:"+(endTime-startTime));
	}

第三に、集約分散読み取りと書き込み

1.分散読み出し(散乱を読み込み):データチャネルバッファの複数の分散

2. 集約書き込み(ギャザリングを書き込み):通路内にデータバッファの複数の集約

3.コード

public class Test004 {
    public static void main(String[] args) throws IOException {
        RandomAccessFile raf1 = new RandomAccessFile("e://test.txt", "rw");
        // 1.获取通道
        FileChannel channel = raf1.getChannel();
        // 2.分配指定大小的指定缓冲区
        ByteBuffer buf1 = ByteBuffer.allocate(100);
        ByteBuffer buf2 = ByteBuffer.allocate(1024);
        // 3.分散读取
        ByteBuffer[] bufs = { buf1, buf2 };
        channel.read(bufs);
        for (ByteBuffer byteBuffer : bufs) {
            // 切换为读取模式
            byteBuffer.flip();
        }
        System.out.println(new String(bufs[0].array(), 0, bufs[0].limit()));
        System.out.println("------------------分算读取线分割--------------------");
        System.out.println(new String(bufs[1].array(), 0, bufs[1].limit()));
        // 聚集写入
        RandomAccessFile raf2 = new RandomAccessFile("e://2.txt", "rw");
        FileChannel channel2 = raf2.getChannel();
        channel2.write(bufs);
    }
}

第四に、の終わり

常に信念を貫きます!!!

公開された122元の記事 ウォン称賛64 ビュー50000 +

おすすめ

転載: blog.csdn.net/chenmingxu438521/article/details/103968684