가자미의 개발이야기

[자바] NIO 기반 입출력 본문

Java/자바 기본 문법

[자바] NIO 기반 입출력

가자미 2021. 3. 1. 14:44

IO 스트림으로 입출력을 다루면 성능 쪽에 불만족하는 경우가 생긴다.

이를 NIO 기반 입출력으로 해결한다.

 

NIO의 채널

데이터 입출력을 위한 통로.

스트림과는 다르게 양방향으로 이동 가능.

반드시 버퍼에 연결해서 사용

 

채널 기반 데이터 입출력 경로

데이터-버퍼-채널-파일

 

 

NIO기반 파일 복사 예제

public static void main(String[] args) {
		Path src = Paths.get("src.txt");
		Path dst = Paths.get("dst.txt");
		
		//하나의 버퍼 생성
		ByteBuffer buf = ByteBuffer.allocate(1024);
		
		//try에서 두 개의 채널 생성
		try(FileChannel ifc = FileChannel.open(src, StandardOpenOption.READ);
				FileChannel ofc = FileChannel.open(dst, StandardOpenOption.WRITE, StandardOpenOption.CREATE)){
			int num;
			while(true) {
				num = ifc.read(buf);	//채널 ifc에서 버퍼 읽어들임
				if(num==-1)	//읽어 들인 데이터가 없다면
					break;
				buf.flip();	//버퍼를 쓰기모드 변환!
				ofc.write(buf);	//버퍼에서 채널 ofc로 데이터 전송
				buf.clear();	//버퍼 지우기
			}
		}
		catch(IOException e) {
			e.printStackTrace();
		}
	}

 

버퍼의 포지션과 flip 활용 예제

public static void main(String[] args) {
		Path fp = Paths.get("data.txt");
		
		//하나의 버퍼 생성
		ByteBuffer wb = ByteBuffer.allocate(1024);
		wb.putInt(120);
		wb.putDouble(0.94);
		
		//하나의 채널 생성
		try(FileChannel fc = FileChannel.open(fp, StandardOpenOption.CREATE,StandardOpenOption.READ,StandardOpenOption.WRITE))
		{
			//파일에 쓰기
			wb.flip(); //쓰기모드로 변환
			fc.write(wb);
			
			//파일로부터 읽기
			ByteBuffer rb = ByteBuffer.allocate(1024);//버퍼생성
			fc.position(0);	//채널의 포지션을 맨 앞으로 이동
			fc.read(rb);
			
			// 이하 버퍼로부터 데이터 읽기
			rb.flip();
			System.out.println(rb.getInt());
			rb.position(Integer.BYTES*2);	//버퍼 포지션 이동
			System.out.println(rb.getDouble());
			System.out.println(rb.getDouble());
			
			rb.position(Integer.BYTES);	//버퍼의 포지션 이동
			System.out.println(rb.getInt());
			
		}
		catch(IOException e) {
			e.printStackTrace();
		}
	}