Java 9부터 InputStream 클래스에 readNBytes() 메서드가 새롭게 추가되었습니다. 이 메서드는 입력 스트림에서 요청한 개수만큼의 바이트를 읽어 지정된 바이트 배열(byte array)에 저장하는 역할을 합니다.
readNBytes() 메서드는 다음 세 가지 상황 중 하나가 발생할 때까지 실행을 블로킹(blocking)합니다.
- len 바이트 만큼의 입력 데이터를 모두 읽은 경우
- 스트림의 끝(end of stream)을 감지한 경우
- 예외(exception)가 발생한 경우
또한 이 메서드는 작업이 끝난 후에도 입력 스트림을 자동으로 닫지 않으므로, 필요에 따라 스트림을 직접 관리해야 합니다. 특히 대용량 파일을 처리할 때 파일 전체를 한 번에 메모리에 올리지 않고 필요한 크기만큼만 읽어들이므로, 메모리 부족(OutOfMemoryError) 문제를 예방하는 데 매우 유용합니다.
메서드 시그니처(Syntax)
public int readNBytes(byte[] b, int off, int len) throws IOException
- b: 읽어들인 데이터가 저장될 바이트 배열
- off: 배열 내에서 데이터가 기록되기 시작하는 위치(오프셋)
- len: 읽어들일 최대 바이트 수
- 반환값: 실제로 읽어들인 바이트 수
사용 예제
아래 예제에서는 소스 폴더에 { "JAVA", "PYTHON", "JAVASCRIPT", "SELENIUM", "SCALA"}라는 간단한 데이터를 담은 "Technology.txt" 파일을 미리 생성해 두었습니다.
import java.io.*;
import java.util.stream.*;
import java.nio.*;
import java.nio.file.*;
public class InputStreamReadNByteMethodTest {
InputStream inputStream = InputStreamReadNByteMethodTest.class.getResourceAsStream("Technology.txt");
public void testReadNBytes() throws Exception {
final byte[] data = new byte[10];
inputStream.readNBytes(data, 0, 7);
System.out.println(new String(data));
}
public static void main(String args[]) throws Exception {
InputStreamReadNByteMethodTest t = new InputStreamReadNByteMethodTest();
t.testReadNBytes();
}
}
실행 결과(Output)
"JAVA",
위 코드에서는 크기 10인 바이트 배열을 생성한 뒤, readNBytes(data, 0, 7)을 호출하여 스트림 시작 위치(offset 0)부터 최대 7바이트를 읽어옵니다. 그 결과 파일의 첫 부분에 해당하는 "JAVA", 문자열이 출력되는 것을 확인할 수 있습니다.
이처럼 readNBytes() 메서드는 스트림에서 원하는 길이만큼 정확하게 데이터를 읽어야 하는 상황, 즉 네트워크 통신이나 대용량 파일을 청크(chunk) 단위로 나누어 처리할 때 특히 효과적으로 활용할 수 있습니다.