컴퓨터공학 💻 도서관📚
Part2. 6-14 바이트 단위 입출력 스트림 본문
여기서는 주로 파일 입출력을 얘기한다고 한다.
가장 많이 사용하는 입출력 중 하나가 파일이다.
그래서 파일에서 어떻게 입력이 일어나고, 어떻게 출력을 하는지 살펴본다고 한다.
InputStream
- '바이트 단위 입력 스트림' 최상위 추상 클래스
- InputStream에 많은 추상 메서드가 선언되어 있고 이를 하위 스트림이 상속받아 구현함
- 주요 하위 클래스

- 주요 메서드

read() : 한 바이트 읽어라
readf(byte b[]) : byte array 크기만큼 읽어라
read(byte b[], int off, int len) : b[] 크기의 자료를 b[off] 부터 len 만큼 읽어라
close : 스트림은 반드시 close를 해야 하는데
과거 강의에서 말했듯 OutoCloseable 인터페이스를 임플피멘테이션 한 경우는 close가 자동으로 불린다
그래서 이 메서드는 명시적으로 안 부르는 경우가 요새는 많이 있다.
(표준 입출력 : System.in, out 은 close 안 해도 된다 , 파일이나 다른 얘들을 한다.)
FileInputStream 예제
- 파일에서 한 바이트씩 자료 읽기
public class FileInputStreamTest1 {
public static void main(String[] args) {
FileInputStream fis = null;
try {
fis = new FileInputStream("input.txt");
System.out.println((char)fis.read()); // read() 1번
System.out.println((char)fis.read());
System.out.println((char)fis.read());
} catch (IOException e) { // IoException 이 FileNotFoundException 의 상위 익셉션이어서 이렇게 함 : 이렇게 하면 try 안에 있는 IoExceptino은 모두 여기 걸림
System.out.println(e);
} finally{ // finally 는 오류가 있든 없든 무조건 실행된다.
try {
fis.close();
} catch (IOException e) {
System.out.println(e);
} catch (NullPointerException e){ // NULL 이면 close 하면 안 되서(오류 남) 예외처리 꼭 해줘야 한다.
System.out.println(e); // NullPointerException 이 기억이 안 나면 그냥 Exception e3 이렇게 최상위로 선언하면 된다.
}
}
System.out.println("end");
}
}
- 파일의 끝까지 한 바이트씩 자료 읽기
public class FileInputStreamTest2 {
public static void main(String[] args) {
try(FileInputStream fis = new FileInputStream("input.txt")){ // try () 안에 리소스를 넣으면 AutoClose 되는데 해당 리소소 클래스가 AutoCloseable 인페를 구현해야 한다.
int i;
while ( (i = fis.read()) != -1){ // 반복문으로 파일의 끝(-1 반환)까지 보게 한다.
System.out.println((char)i);
}
System.out.println("end");
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
byte단위는 문자 핸들링이 안 된다.
문자를 핸들링 하려면 File 같은 경우는 File-Reader가 제공이 되서 그걸 쓰거나
System.in 처럼 input.stream.reader 로 감싸서 할 수 도 있다.
- 파일에서 바이트 배열로 자료 읽기 ( 배열에 남아 있는 자료가 있을 수 있음에 유의 )
public class FileInputStreamTest3 {
public static void main(String[] args) {
try (FileInputStream fis = new FileInputStream("input2.txt")){
byte[] bs = new byte[10];
int i;
while ( (i = fis.read(bs)) != -1){ // read() 2번
/*for(byte b : bs){
System.out.print((char)b);
}*/
for(int k= 0; k<i; k++){ // 밑에 설명 있음
System.out.print((char)bs[k]);
}
System.out.println(": " +i + "바이트 읽음" );
}
/*while ( (i = fis.read(bs, 1, 9)) != -1){ 밑에 설명 있음
for(int k= 0; k<i; k++){
System.out.print((char)bs[k]);
}
System.out.println(": " +i + "바이트 읽음" );
}*/
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("end");
}
}
// 출력
// ABCDEFGH 9바이트 밑에 설명 있음
// JKLMNOPQ 9바이트
// STUVWXY 8바이트
read(bs, 1, 9)를 하면 bs 안에는 이렇다 [ 0, A, B, C, D, E, F, G, H, I ] (초기화값이 0인데 1번 인덱스부터 저장했다)
여기서 출력을 for(int k= 0; k<i; k++) 0부터 i-1까지 함 --> 즉, 인덱스 0~8까지 함 ( I 는 인덱스 9여서 출력 안 됨 )
그런데 bs[0] 에는 읽은 데이터가 없고 0임 --> 그래서 (char)0 은 화면에 보이지 않는다
그래서 화면에는 8개의 알파벳이 보이게 된다. ABCDEFGH
1바이트로 다룰 수 있는 것 : 알파벳, 숫자, 특수문자
2~3 바이트로 다루는 것 : 한글, 일부 특수문자

for(int k= 0; k<i; k++) 이 코드에서 k<i 를 안 해주면 버퍼에 남아 있는 자료가 출력된다
OutputStream
- 바이트 단위 출력 스트림 최상위 추상 클래스
- 많은 추상 메서드가 선언되어 있고 이를 하위 스트림이 상속받아 구현함
- 주요 하위 클래스

- 주요 메서드

flush() 와 close() 메서드
- 출력 버퍼를 비울때 flush() 메서드를 사용
(우리가 출력을, write() 를 하면 바로바로 써지는게 아닌다. 출력 버퍼라는게 있는데
특히 이제 소켓 같은 거를 쓰면, 네트워크를 하면 네트워크는 데이터 한 바이트 쓴다고 바로바로 날아가는 게 아니라,
어느 정도 소켓이 사용하는 버퍼가 있고, 그 버퍼에, 출력용 버퍼에 데이터가 쌓이면, 한꺼번에 날아간다.
그런데 데이터가 일정 부분 안 쌓이면 안 날아갈 수 도 있다 , 출력이 일어나지 않을 수도 있다
그래서 강제적으로 이때 버퍼를 비운다.
화장실에서 물 내리는 걸 flushing 한다고 한다. 그래서 버퍼를 비우는, 강제적으로 비우게 하는게 flush이다.) - close() 메서드 내부에서 flush()가 호출되므로 close()메서드가 호출되면 출력 버퍼가 비워짐
FileOutputStream 예제
- 파일에 한 바이트씩 쓰기
public class FileOutputStreamTest1 {
public static void main(String[] args) {
try(FileOutputStream fos = new FileOutputStream("output.txt")){ // 밑에 설명 있음
fos.write(65); //A
fos.write(66); //B
fos.write(67); //C
}catch(IOException e) {
e.printStackTrace();
}
System.out.println("출력이 완료되었습니다.");
}
}
인풋 스트림은 읽으려는 파일이 없으면 FileNotFoundException 오류가 나는데
아웃풋 스트림은 파일이 없으면 파일을 만들어준다
아웃풋 스트림의 Default 는 Overwrite(덮어 쓰다)이다.
(내가 한 파일에 글을 다시 쓸 때 , 파일을 쓰고 닫았다가 다시 쓸 때 , 다시 쓸려고 열어서 쓰면 처음부터 쓴다.)
(로그와 같이 뒤에 이어서 쓰고 싶으면 2번째 매개변수 자리에 true 라고 쓰면 된다. FileOutputStream("output.txt", true)
2번째 매개변수인 Append 여부의 Default 는 false 이다.)
- byte[ ] 배열에 A-Z 까지 넣고 배열을 한꺼번에 파일에 쓰기
public class FileOutputStreamTest2 {
public static void main(String[] args) throws IOException {
FileOutputStream fos = new FileOutputStream("output2.txt",true);
try(fos){ //java 9 부터 제공되는 기능
byte[] bs = new byte[26];
byte data = 65; //'A' 의 아스키 값
for(int i = 0; i < bs.length; i++){ // A-Z 까지 배열에 넣기
bs[i] = data;
data++;
}
fos.write(bs); //배열 한꺼번에 출력하기
}catch(IOException e) {
e.printStackTrace();
}
System.out.println("출력이 완료되었습니다.");
}
}
- byte[ ] 배열의 특정 위치에서 부터 정해진 길이 만큼 쓰기
public class FileOutputStreamTest3 {
public static void main(String[] args) {
try(FileOutputStream fos = new FileOutputStream("output3.txt"))
{
byte[] bs = new byte[26];
byte data = 65; //'A' 의 아스키 값
for(int i = 0; i < bs.length; i++){ // A-Z 까지 배열에 넣기
bs[i] = data;
data++;
}
fos.write(bs, 2, 10); // 배열의 2 번째 위치부터 10 개 바이트 출력하기
}catch(IOException e) {
e.printStackTrace();
}
System.out.println("출력이 완료되었습니다.");
}
}
'✅🌲강의 복습 노트 > 패캠 JavaSpring 강의,코드 복습' 카테고리의 다른 글
| Part2. 6-16 여러가지 보조 스트림 클래스들 (0) | 2025.08.31 |
|---|---|
| Part2. 6-15 문자 단위 입출력 스트림 (1) | 2025.08.29 |
| Part2. 6-13 표준 입출력 스트림 (0) | 2025.08.22 |
| Part2. 6-12 자바의 입출력을 위한 I/O 스트림 (통합 연산 도구) (0) | 2025.08.21 |
| Part2. 6-11 오류의 로그를 남기기 - java.util.logging.Logger 활용 (이해 잘 안 됨...) (3) | 2025.08.15 |