풀스택 개발 학습 과정/백엔드(Java, Spring)

[자바] 입출력 I/O 와 Stream

육츠 2024. 1. 30. 18:59

I/O

- input (입력)
- output (출력) : 컴퓨터 내부 또는 외부의 장치와 프로그램간의 데이터를 주고 받는 것을 말한다.

Stream

: 두 대상을 연결하고 데이터를 전송하는 연결 통로이다.
- 단방향 통신만 가능하기 때문에 하나의 스트림으로 입력과 출력을 동시에 처리할 수 없다.

 

바이트 기반 스트림 - InputStream / OutputStream

- 1 바이트 사용 ( 그림 , 음악 , 동영상 등)

 

# InputStream

- File 을 읽어올때는 Exception 처리의 주의하며 진행한다.
- 'song.txt' = 'abcdeefg' 

package iostream;

import java.io.FileInputStream;
import java.io.IOException;

public class InputStreamTest01 {

	public static void main(String[] args) {
		FileInputStream fis = null;
		try {
			fis = new FileInputStream("song.txt");


			// a 만 읽어옴
			// read 자체가 int를 반환 ==> 형변환
			while(true) {
				int ch = fis.read();
				if(ch == -1) break;
				System.out.print((char)ch);
			}
			System.out.println("끝");

		} catch (IOException e) {
			System.out.println("파일이 없거나 오픈할 수 없습니다.");
			e.printStackTrace();
		} finally {
			try {
				if(fis != null) fis.close();
				// 열려야 닫을 수 있다.
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

}

abcdefg

코드 의미
while(true) {
    int ch = fis.read();
    if(ch == -1) break;
- read 자체가 int를 반환하기 때문에 int 로 읽어온다.
- 끝은 -1을 반환하기 때문에 다 읽어오면 break
finally {
    try {
        if(fis != null) fis.close();
파일은 열려야만 닫을 수 있다.
파일이 열리지 않으면 null 을 가지고 있도록 초기화 시켰기 때문에 null이 아닐때만 close를 한다.

** read 의 반환타입이 int 인 이유 : read의 반환값 범위가 0~255 와 -1 이기 때문이다.

 

# OutputStream

package iostream;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class OutputStreamTest03 {

	public static void main(String[] args) {
		FileOutputStream fos = null;
		String data = "abcdefghijklmn";

		try {
			fos = new FileOutputStream("target.txt");

			try {
				for(int i =0; i<data.length(); ++i)
					fos.write(data.charAt(i));
				
				System.out.println("저장완료");
			} catch (IOException e) {
				e.printStackTrace();
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}finally {
			try {
				if( fos != null) fos.close();
			}catch(IOException e) {
				e.printStackTrace();
			}
		}
	}

}

 

문자기반 스트림 - Reader / Writer 

- 2바이트 사용
- InputStream -> Reader
- OutputStream -> Writer

 

# Reader

- 'song.txt'  = ' 나리나리 개나리 입에 따다 물고요 \n'
- 영어가 아니면 문자로 읽어와야 한다.

package iostream;

import java.io.FileReader;
import java.io.IOException;

public class InputReaderTest02 {
// 문자열읽을때 
	public static void main(String[] args) {
		FileReader fr = null;
		try {
			fr = new FileReader("song.txt");

			while(true) {
				int ch = fr.read();
				if(ch == -1) break;
				System.out.print((char)ch);
			}
			System.out.println("끝");

		} catch (IOException e) {
			System.out.println("파일이 없거나 오픈할 수 없습니다.");
			e.printStackTrace();
		} finally {
			try {
				if(fr != null) fr.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

}

나리나리 개나리 입에 따다 물고요

 

# 입력 + 출력

- 하나의 스트림으로 입력과 출력을 동시에 처리할 수 없기 때문에 두 개의 Stream 을 생성해야한다.

package iostream;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class IOStreamTest04 {

	public static void main(String[] args) {
		FileInputStream fis = null;
		FileOutputStream fos = null;
		try {
			fis = new FileInputStream("HSH.jpg");
			fos = new FileOutputStream("HSH_target.jpg");

			while(true) {
				int ch = fis.read();
				if(ch == -1) break;
				
				fos.write(ch);
			}
			System.out.println("복사완료! ");

		} catch (IOException e) {
			System.out.println("파일이 없거나 오픈할 수 없습니다.");
			e.printStackTrace();
		} finally {
			try {
				if(fis != null) fis.close();
				
				if(fos != null) fos.close();
				// close 안하면 그림이 깨지거나 이상해지기 때문에 반드시 close
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

}
코드 의미
while(true) {
    int ch = fis.read();
    if(ch == -1) break;

    fos.write(ch);
}
사진 읽어오고 사진의 복사본 저장
if(fos != null) fos.close(); 하지 않으면 원본이 훼손된다. 때문에 반드시 close 해야한다.