Java

Java NIO

jamie. 2020. 2. 6. 09:39
반응형

Java NIO(JDK 1.4 ~)

JDK 1.4 ~ NIO(New IO) 추가

추가된 이유 : 속도때문

Stream을 사용하지 않고 Channel과 Buffer를 사용

Channel

간단하게 객체만 생성하여 read()나 write(), close() 메서드만 불러주면 됨

중간에서 처리하는 도매상같은 것

Buffer 

도매상에서 물건을 사고, 소비자에게 물건을 파는 소매상 같은 것

예제

package study;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;

public class NIOTest {
    public static void main(String[] args) {
        NIOTest test = new NIOTest();
        test.basicWriteAndRead();
    }

    public void basicWriteAndRead() {
        String fileName = "/Users/hs/test.txt";
        try {
            writeFile(fileName, "My Name is Jamie");
            readFile(fileName);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void writeFile(String fileName, String data) throws Exception {
    	// 파일을 쓰기위한 FileChannel 객체 생성 - FileOutputStream(파일명).getChannel()
        FileChannel channel = new FileOutputStream(fileName).getChannel();
        byte[] byteData = data.getBytes();
        // ByteBuffer의 static wrap(저장할 Byte배열) 메서드 호출시 ByteBuffer 객체 생성
        ByteBuffer buffer = ByteBuffer.wrap(byteData);
        // FileChannel의 write()메서드에 buffer를 넘겨주면 파일에 쓰게 됨
        channel.write(buffer);
        // 채널 닫음
        channel.close();
    }

    public void readFile(String fileName) throws Exception {
    	// 파일을 읽기위한 FileChannel 객체 생성 - FileInputStream(파일명).getChannel()
        FileChannel channel = new FileInputStream(fileName).getChannel();
        // ByteBuffer의 static allocate(데이터 저장크기) 메서드 호출시 buffer 객체 생성 가능
        ByteBuffer buffer = ByteBuffer.allocate(1024);
        // FileChannel의 read()메서드에 buffer를 넘겨주면 데이터를 해당 버퍼에 담음
        channel.read(buffer);
        // buffer에 담겨있는 데이터의 가장 앞으로 이동 (위치 찍고 되감기)
        buffer.flip();
        // 데이터가 더 남아있는지 확인 - 위치찍은곳까지
        while(buffer.hasRemaining()) {
        	// get()으로 데이터를 한 바이트씩 읽음
            System.out.print((char)buffer.get());
        }
        // 채널 닫음
        channel.close();
    }
}

////////////////////////////////////////////////////////////////////
My Name is Jamie
Process finished with exit code 0

NIO의 Buffer 클래스

java.nio.Buffer 클래스를 확장하여 사용

종류

ByteBuffer / CharBuffer / DoubleBuffer / FloatBuffer / IntBuffer / LongBuffer / ShortBuffer 등

버퍼의 상태 및 속성을 확인하기 위한 메서드

// 버퍼에 담을 수 있는 크기 리턴
int capacity()

// 버퍼에서 읽거나 쓸 수 없는 첫 위치 리턴
int limit()

// 현재 버퍼의 위치 리턴
int position()

/* 관계
 * 0 <= position() <= limit() <= capacity()
 */

위치를 변경하는 메서드

// limit 값을 현재 position으로 지정 후 position을 0으로 이동(가장 앞)
Buffer flip()

// 현재 position을 mark
Buffer mark()

// 버퍼의 position을 mark 한 곳으로 이동
Buffer reset()

// 현재 버퍼의 position을 0으로 이동 - flip()과 달리 limit 값을 변경하지 않음
Buffer rewind()

// limit-position 계산 결과를 리턴 - limit까지 읽음
int remaining()

// position과 limit 값이 다를 경우 true 리턴 - limit까지 읽음
boolean hasReamaining()

// 버퍼를 지우고 현재 position을 0으로 이동하며, limit 값을 버퍼의 크기로 변경
Buffer clear()

예제

package study;

import java.nio.IntBuffer;

public class BufferTest {

    public static void main(String[] args) {
        BufferTest test = new BufferTest();
        test.checkBuffer();
    }
    public void printBufferStatus(String job, IntBuffer buffer) {
        System.out.println("Buffer " + job + " !!!");
        System.out.format("Buffer position=%d remaining=%d limit=%d\n",
                buffer.position(), buffer.remaining(), buffer.limit());
    }

    public void checkBuffer() {
        try {
            IntBuffer buffer = IntBuffer.allocate(1024);
            for(int loop = 0; loop < 10; loop++) {
                buffer.put(loop);
            }
            System.out.println("Buffer capacity = " + buffer.capacity());
            System.out.println("Buffer limit    = " + buffer.limit());
            System.out.println("Buffer position = " + buffer.position());
            buffer.flip();
            System.out.println("Buffer flipped !!!");
            System.out.println("Buffer limit    = " + buffer.limit());
            System.out.println("Buffer position = " + buffer.position());
            System.out.println("--------------------------");
            buffer.get();
            printBufferStatus("get", buffer);
            buffer.mark();
            printBufferStatus("mark", buffer);
            buffer.get();
            printBufferStatus("get", buffer);
            buffer.reset();
            printBufferStatus("reset", buffer);
            buffer.rewind();
            printBufferStatus("rewind", buffer);
            buffer.clear();
            printBufferStatus("clear", buffer);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
////////////////////////////////////////////////////////////////////////////
Buffer capacity = 1024
Buffer limit    = 1024
Buffer position = 10
Buffer flipped !!!
Buffer limit    = 10
Buffer position = 0
--------------------------
Buffer get !!!
Buffer position=1 remaining=9 limit=10
Buffer mark !!!
Buffer position=1 remaining=9 limit=10
Buffer get !!!
Buffer position=2 remaining=8 limit=10
Buffer reset !!!
Buffer position=1 remaining=9 limit=10
Buffer rewind !!!
Buffer position=0 remaining=10 limit=10
Buffer clear !!!
Buffer position=0 remaining=1024 limit=1024

Process finished with exit code 0

예제 2

반응형