2024.04.24 - [공부한 기록/Programming Language] - Java - 스트림 Stream
입출력 처리
여기서 다루는 스트림의 개념은 이전 스트림 관련글과 같다. 스트림에 관한 내용을 다시 상기하려면 위 링크를 누르고 읽어보자!
입출력(I/O)은 단어 그대로, 시스템 및 소프트웨어의 입력과 출력을 의미하는 것은 바로 알 수 있을 것이다. 이번에는 스트림의 입출력에 대해 알아보도록 하겠다!
입출력 스트림은 크게 2가지로 나뉘는데, 바이트(8비트 단위) 스트림과 문자(16비트 단위) 스트림이다. 밑의 직관적인 그림을 참고해보자.
바이트 스트림 Byte Stream
1Byte는 8Bit이다. java에서는 이 바이트 단위로 입출력을 할 수 있는 클래스가 제공된다. 모든 바이트 스트림 클래스들은 추상 클래스인 InputStream과 OutputStream에서 파생되고, 각 명칭에는 이 이름들이 들어가 있다!
바이트 단위의 이진 데이터를 다루므로 이미지나 동영상 파일을 처리할 때 유용하다.
Input/OutputStream 클래스가 제공하는 메소드는 다음과 같다. 자주 쓰이는 메소드 몇 개만 알아놓자.
InputStream
int available() | 현재 읽을 수 있는 바이트 수를 반환 |
void close() | 스트림을 닫음 |
void mark(int readlimit) | 현재 위치를 표시 |
boolean markSupported() | mark와 reset이 지원되는지 여부 반환 |
int read() | 한 바이트를 읽고 int로 반환 |
int read(byte[] b) | b의 길이만큼 바이트를 읽고 개수를 반환 |
int read(byte[] b, int off, int len) | 지정된 바이트 배열의 특정 위치에서 시작하여 len 바이트를 읽음 |
void reset() | 마지막 mark 위치로 되돌림 |
long skip(long n) | n 바이트만큼 건너뜀 |
OutputStream
void close() | 스트림을 닫음 |
void flush() | 버퍼에 남은 모든 바이트를 출력 |
void write(int b) | 지정된 바이트를 스트림에 씀 |
void write(byte[] b) | 바이트 배열 b의 내용을 스트림에 씀 |
void write(byte[] b, int off, int len) | 바이트 배열의 특정 부분을 스트림에 씀 |
여기서 몇 가지 알아야 할 점이 있다.
- read() 메소드의 반환 값은 int 타입의 0~255인 ASCII 값이며, 더 이상 읽은 데이터가 없을 때(EOF)는 -1을 반환함.
- write() 메소드의 반환 타입은 파라미터마다 다른데, 파라미터가 배열일 때는 byte[]이고, 배열이 아닐 때는 int 값임.
- 각 메소드는 IOException을 발생할 수 있으므로 해당 메소드를 호출하는 곳에서 처리해야 함.
FileInput/OutputStream
시스템에 있는 모든 파일을 바이트 단위로 읽거나 쓸 수 있다. FileNotFoundException 이 발생할 수 있으니 이를 위한 처리 코드가 필요하다.
public static void main(String[] args) {
String input = "D:\\Temp\\org.txt";
String output = "D:\\Temp\\dup.txt";
try (FileInputStream fis = new FileInputStream(input);
FileOutputStream fos = new FileOutputStream(output)) {
int c;
while ((c = fis.read()) != -1)
fos.write(c);
} catch (IOException e) {
}
}
BufferedInput/OutputStream
버퍼 Buffer의 개념에 대해 알아둘 필요가 있다. 이번에도 찾아오는 예시 들기로 개념을 명확히 알자. 나는 매일마다 음료수를 사서 마신다. 이 음료수는 걸어서 5분인 편의점에서 사온다. 그런데 매일 같이 편의점에 가서 음료수를 사오기는 역시 번거롭다! 마시는 건 금방인데 사오는 건 오래 걸리기 때문이다. 그럴 때 냉장고를 하나 들여왔다. 이제 편의점에서 음료수를 잔뜩 사와서 냉장고에 쟁여놓고 언제든 빠르게 꺼내올 수 있다.
버퍼 개념이 얼추 이해됐을 것이다. 여기서 실질적으로 쓰이는 버퍼는 스트림과 프로그램 간의 데이터 효율적으로 전송하기 위해 사용하는 메모리이다. 입출력 장치와 프로그램 간의 속도 차이가 크게 날 때 버퍼를 사용하면 매우 효율적이다. 버퍼를 사용하지 않을 때와 사용할 때의 속도 차이는 3배 이상 나는 경우도 있다!
String org = "C:\\Program Files (x86)\\Internet Explorer\\iexplore.exe";
String dst = "D:\\Temp\\iexplore1.exe";
try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream(org));
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(dst));) {
while (bis.available() > 0) {
int b = bis.read();
bos.write(b);
}
bos.flush();
} catch (IOException e) {
}
문자 스트림 Character Stream
문자 단위 16비트로 입출력하는 클래스다. 기본 추상 클래스에서 파생된 클래스는 모두 Reader와 Writer의 이름을 갖는다.
문자를 처리할 때에 유용하다.
위에서 언급한 Buffer, File 관련 클래스는 문자 스트림에서는 다음과 같다.
- FileReader와 FileWriter는 파일 입출력 클래스로, 파일에서 문자 데이터를 읽거나 파일에 문자 데이터를 저장할 때 사용
- InputStreamReader및 OutputStreamWriter는 바이트 스트림과 문자 스트림을 연결하는 스트림으로 사용
- BufferedReader와 BufferedWriter는 데이터를 효율적으로 전송하려고 버퍼로 처리할 때 사용
try (FileInputStream fi = new FileInputStream(inputPath);
InputStreamReader in = new InputStreamReader(fi, "US-ASCII")) {
int c;
System.out.println(in.getEncoding());
while ((c = in.read()) != -1)
System.out.print((char) c);
} catch (IOException e) {
}
'기록 > Programming Language' 카테고리의 다른 글
Java - 파일 관리 (0) | 2024.06.06 |
---|---|
Java - GUI (0) | 2024.06.06 |
Java - 스트림 Stream (0) | 2024.04.24 |
Java - 컬렉션 프레임워크 Collection Framework (0) | 2024.04.20 |
Java - 람다식과 함수형 인터페이스(Predicate, Consumer, Supplier, Function, Operator) (0) | 2024.04.17 |