바이트 단위 스트림
1) InputStream
바이트 단위로 읽는 스트림 중 최상위 스트림이다. InputStream은 추상 메서드를 포함한 추상 클래스로서 하위 스트림 클래스가 상속받아 각 클래서 역할에 맞게 추상 메서드의 기능을 구현한다. 그렇다면 주로 사용하는 하위 클래스 종류를 알아보자.
FileInputStream - 파일에서 바이트 단위로 자료를 읽는다.
ByteArrayInputStream - 바이트 배열 메모리에서 바이트 단위로 자료를 읽는다.
FilterInputStream - 기반 스트림에서 자료를 읽을 때 추가 기능을 제공하는 '보조 스트림'의 상위 클래스이다.
InutStream은 바이트 자료를 읽기 위해 int형을 반환하는 read()메서드를 제공한다. 한 바이트를 읽는데 왜 반환값이 int일까?
- 더 이상 읽어들일 자료형이 없는 경우 -1을 반환하기 때문이다!
- FileInputStream
파일에서 바이트 단위로 자료를 읽어 들일 때 사용하는 스트림 클래스이다. 스트림을 사용하기 위해서는 스트림 클래스를 생성해여한다. FileInputStream의 생성자를 보면 다음과 같다.
FileInputStream(String name) - 파일 이름을 매개변수로 받아 입력 스트림을 생성한다.
FileInputStream(File f) - 파일 클래스 정보를 매개변수로 받아 입력 스트림을 생성한다.
package stream;
import java.io.FileInputStream;
import java.io.IOException;
public class FileInputStreamTest1 {
public static void main(String[] args) {
FileInputStream fis = null;
try {
fis = new FileInputStream("input.txt"); //FileInputStream(String name) 생성자로 스트림 생성
System.out.println(fis.read());
System.out.println(fis.read());
System.out.println(fis.read()); // 입력 스트림으로부터 한 바이트의 자료를 읽는다. 읽은 자료의 바이트 수를 반환한다.
} catch (IOException e) {
System.out.println(e);
}
finally {
try{
fis.close(); //열린 스트림을 파이널리 블록에서 닫아준다.
} catch(IOException e) { //스트림이 null인 경우
System.out.println(e);
}
}
System.out.println("end");
}
}
나는 input.txt 파일을 생성하지 않은 상태에서 코드를 실행시켰다. 예외를 발생시켜 트라이 캐치문을 실행하기 위해서다.
프로그램을 실행해보면 각 FileNotFoundException 예외, 파이널리 구문에서 파일을 닫는 호출 부분에서는 스트림이 생성되지 않았으므로 NullPointException 에러가 발생한다.
수행 결과를 통해 또 한 가지 알 수 있는 점은 "end"의 출력을 통해 확인할 수 있다. 예외처리를 하면 프로그램 수행을 중단시키지 않는다는 점!
이후에 input.txt 파일을 만들고, ABC를 입력한 후 저장하여 위 코드를 실행시켰다. 제대로 동작한다.
나는 세 바이트의 단어를 입력해서 출력 부분을 세 개만 적었는데, 파일에 내용이 얼만큼 있는지 모르는 상태에서 출력을 하는 경우가 훨씬 많을 것이다. 이럴땐 어떻게 할까?
이렇게 바꾸어 주면된다.
try {
fis = new FileInputStream("input.txt"); //FileInputStream(String name) 생성자로 스트림 생성
/*
System.out.println(fis.read());
System.out.println(fis.read());
System.out.println(fis.read()); // 입력 스트림으로부터 한 바이트의 자료를 읽는다. 읽은 자료의 바이트 수를 반환한다.
*/
int i;
while((i = fis.read()) != -1) {
System.out.println((char) i ); // i값이 -1이 아닌동안 read메서드로 한 바이트를 반복해서 읽는다.
}
read() 메서드로 파일을 읽는 경우 파일의 끝에 도달하면 -1을 반환한다.
while 문을 통해 i값이 -1이 아닌 한 while문이 계속 수행되도록 코드를 작성했다.
그런데, 이렇게 한 바이트씩 자료를 읽으니 속도가 매우 느리다. 배열을 사용하여 한꺼번에 많이 읽으면 처리 속도가 훨씬 빠를 것이다. 이럴 경우 선언하는 메서드가 있다.
int read(byte[] b)
선언한 바이트 배열의 크기만큼 한꺼번에 자료를 읽는다. 읽어들인 자료의 수를 반환한다.
package stream;
import java.io.FileInputStream;
import java.io.IOException;
public class FileInputStreamTest3 {
public static void main(String[] args) {
try(FileInputStream fis = new FileInputStream("input2.txt")) {
byte[] bs = new byte[10]; //10 바이트 배열 선언
int i;
while((i = fis.read(bs)) != -1) { //읽어들인 반환값이 -1이 아닐때까지 << 파일의 끝에 도달할 때까지 읽는다)
for(byte b: bs) {
System.out.println((char)b);
}
System.out.println(":" + i+ "바이트 읽음");
}
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("end");
}
}
'공부 STUDY > JAVA' 카테고리의 다른 글
[JAVA] 자바 입출력과 스트림 - (4) | 문자 단위 스트림 (0) | 2023.01.24 |
---|---|
[JAVA] 자바 입출력과 스트림 - (3) | 바이트 단위 스트림 - OutputStream (0) | 2023.01.24 |
[JAVA] 자바 입출력과 스트림 - (1) | scanner 클래스와 Console 클래스에대해 알아보자 (0) | 2023.01.23 |
[JAVA] 사용자 정의 예외 클래스 구현하기 | 아이디 설정 조건에서 예외 발생에대한 클래스를 구현해보자! | 사용자 정의 예외 (0) | 2023.01.23 |
[JAVA] 자바의 예외처리(Exception) | try-catch-finally 문, try-with-resource 문 (0) | 2023.01.23 |