둘째, 자바 프로그래밍 NIO 기초 (직접 및 간접 버퍼 버퍼)

I. 배경

이전 블로그를 착수 1. 우리는 오늘, 법석이 오늘 요약하기 시작했다 NIO 프로그램에서 공부를 계속합니다. : 특정 기사를 참조 할 수 있습니다 https://blog.csdn.net/chenmingxu438521/article/details/103967066

둘째, 버퍼로 버퍼링 직간접 구별

1. 비 직접 버퍼 ()에 할당하여 버퍼를 할당하는 방법은 JVM에서의 버퍼 메모리에 기초

 2. 직접 버퍼 ()에 의해 직접 allocateDirect 버퍼를 할당하기위한 방법은, 상기 버퍼가 물리적 인 메모리에 설정된다. 효율성을 향상시킬 수 있습니다

분석 (3)

3.1. 바이트 버퍼 역시 직접 또는 간접이다. 다이렉트 byte 버퍼 경우, Java 가상 머신이 직접 버퍼에 기본 I / O 작업을 수행하기 위해 최선을 다할. 즉, 기본 운영 체제, 기본 I / (또는 이상) O 작업에 대한 각 호출하기 전에, 가상 머신은 중간 버퍼 버퍼의 내용을 복사 피하려고 (또는 중간 버퍼에서 콘텐츠를 복사 ).

3.2 (예를 들어 : 파일, 소켓)에 연결 입출력 장치에 채널 개방을 나타냅니다. 필요한 경우 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