자바의 정석 15장
이 글은 Java의 정석 3rd Edition을 읽고 정리한 내용입니다.
Chapter 15

입출력 I/O
1. 자바에서의 입출력
1.1 입출력이란?
I/O란 Input과 Output의 약자로 입력과 출력, 간단히 줄여서 줄여서 입출력이라고 한다. 입출력은 컴퓨터 내부 또는 외부의 장치와 프로그램간의 데이터를 주고받는것을 말한다.
1.2 스트림
두 대상을 연결하고 데이터를 전송할 수 있는 무언가가 필요한데 이것을 스트림이라고 정의했다.
스트림은 데이터를 운반하는데 사용되는 연결통로이다.
스트림은 단방향통신만 가능하기 때문에 입력과 출력을 동시에 수행하려면 입력스트림과 출력스트림 모두 2개의 스트림이 필요하다.
1.3 바이트기반 스트림
스트림은 바이트 단위로 데이터를 전송하며 입출력 대상에 따라 다음과 같은 입출력스트림이 있다.
입력 스트림 | 출력스트림 | 입출력 대상의 종류 |
FileInputStream | FileoutputStream | 파일 |
ByteArrayInputStream | ByteArrayOutputStream | 메모리(byte 배열) |
AudioInputStream | AudioOutputStream | 오디오 장치 |
자바에서는 java.io패키지를 통해서 많은 종류의 입출력관련 클래스들을 제공하고 있으며 표준화된 방법을 제공함으로써 입출력의 대상이 달라져도 동일한 방법으로 입출력이 가능하다.
1.4 보조 스트림
실제 데이터를 주고받는 스트림이 아니기 때문에 데이터를 입출력할 수 없다
스트림의 기능을 향상시키거나 새로운 기능을 추가할 수 있다.
입력 | 출력 | 설명 |
FilterInputStream | FilterOutputStream | 필터를 이용한 입출력 처리 |
BufferdInputStream | BufferedOutputStream | 버퍼를 이용한 입출력 성능 향상 |
DataInputStream | DataOutputStream | int,float와 같은 기본형 단위로 데이터를 처리하는 기능 |
SequenceInputStream | 없음 | 두 개의 스트림을 하나로 연결 |
LineNumberInputStream | 없음 | 읽어 온 데이터의 라인 번호를 카운트 |
ObjectInputStream | ObjectOutputStream | 데이터를 객체단위로 읽고 쓰는데 사용 주로 파일을 이용하여 객체 질렬화와 관련있음 |
없음 | PrintStream | 버퍼를 이용하며, 추가적인 print관련 기능 |
PushbackInputStream | 없음 | 버퍼를 이용해서 읽어 온 데이터를 다시 되돌리는 기능 |
1.5 문자 기반 스트림 - Reade, Writer
java에선 chat는 unit 코드를 사용하니 때문에 1byte가 아닌 2byte를 이용한다 그러기에 바이트 기반의 스트림이 아닌 문자 기반의 스트림을 제공한다.
바이트기반 스트림과 문자기반 스트림은 이름만 조금 다를 뿐 활용방법은 거의 같다.
InputStream -> Reader
OuputStream -> Writer
2.바이트기반 스트림
21.InputStream과 OutputStream
InputStream과 OutputStream은 바이트기반의 스트림의 조상이며 다음과 같은 메서드가 선언 되어있다.
mark()와 reset()을 사용하여 읽은 데이터를 되돌려서 다시 읽을 수 있다. 이 기능을 지원하는지 markSuppoprted()를 통해서 알수 있다.
스트림을 사용한 후 반드시 close()를 호출해서 닫아 주어야 한다.
2.2 ByteArrayInput과 ByteArrayOutputStream
바이트 배열에서 데이터를 입출력 한느데 사용되는 스트림이다.
주로 다른 곳에 입출력하기 전에 데이터를 임시로 바이트배열에 담아서 변환 등의 작업을 하는데 사용된다.
2.3 FileInputStream과 FileOutputStream
파일에 입출력을 하기 위한 스트림이다. 실제로 가장 많이 사용되는 스트림 중 하나이다.
생성자 | 설 명 |
FileInputStream(String name) | 저장된 파일이름을 가진 실제 파일과 연결된 FileInputStream을 생성한다. |
FileInputStream(File file) | 파일의 이름이 String이 아닌 File인스턴스로 지정해주어야 하는 점을 제외하고 FileInputStream(String name)와 같다 |
FileInputStream(FileDescriptor fdObj) | 파일 디스크립터로 FileInputStream을 생성한다. |
FileOutpustStream(String name,boolean append) | 지정된 파일이름을 가진 실제 파일과 연결된 FileOutputStream을 생성한다. 두번째 인자인 append를 true로 하면 출력 시 기존의 파일내용의 마지막에 덧붙인다. false면 기존의 파일내용을 덮어쓰게 된다. |
FileOutputStream(File file) | 파일의 이름을 String이 아닌 File인스턴스로 지정해주어야 하는 점을 제외하고 FileOutputStream(String name)과 같다 |
FileOutputStream(File file,boolean append) | 파일의 이름을 String이 아닌 File인스턴스로 지정해주어야 한는 점을 제외하고 FileOutputStream(String name,boolean append)과 같다. |
FileOutputStream(FileDescriptor fdObj) | 파일 디스크립터로 FileOutputStream을 생성한다. |
3. 바이트기반의 보조스트림
3.1 FilterInputStream과 FilterOutputStream
FilterInputStream과 FilterOuputStream은 InputStream과 OutputStream객체를 둘러싸서 그위에 추가적인 기능이나 속성을 부여하며 보조 스트림을 구현한때 사용되는 Stream이다
3.2 BufferdInputStream과 BufferdOutputStream
스트림의 효율을 높이기 위해 사용하는 보조스트림으로 한 바이트씩 입출력을 하는 것보다 버퍼를 이용해 한 번에 여러 바이트를 입출력하는 것이 빠르기 때문에 대부분의 입출력을 Buffer와 Stream을 같이 사용한다,
3.3 DataInputStream과 DataOutputStream
DataInputStream/DateOuputStream은 DataInput/DataOuput 인터페이스를 각각 구현하였기 때문에 데이터를 읽고 쓰는데 byte단위가 아닌 r기본 자료형의 단위로 읽고 쓸수 ㅇ씨다.
출력한 데이터를 읽어 올 때는 출력했을 때의 순서를 염두에 두어야 한다.
3.4 SequenceInputStream
여러 개의 입력스트림을 연속적으로 연결해서 하나의 스트림으로부터 데이터를 읽는 것과 같이 처리할 수 있도록 도와준다.
3.5 PrintStream
데이터를 기반스트림에 다양한 형태로 출력할 수 있는 print,println과 같은 메서드를 오버로딩 하여 제공한다.
PrintStream과 PrintWriter는 거의 같은 기능을 가지고 있지만 PrintWriter가 PrintStream에 비해 다양한 언어의 문자를 처리하는데 더 적합하기 때문에 PrintWriter를 사용하는 것이 좋다.
4.문자기반 스트림
4.1Reader와 Writer
문자기반의 스트림에서는 Reader와 Witer가 조상이다. char배열을 사용한다는 것 이외에는 InputStream/OutputStream의 메서드와 다르지 않다.
4.2 FileReader와 FileWriter
파일로부터 텍스트 데이터를 읽고 파일에 쓰는데 사용된다. FileInputStream/FileOutputStream과 같은 기능을 제공한다.
5.문자열 기반의 보조스트림
5.1BufferdReader와 BufferdWriter
버퍼를 이용해서 입출력의 효율을 높일 수 있도록 해주는 역할을 한다.
5.2 InputStreamReader와 OuputStreamReader
바이트기반 스트림을 문자기반 스트림으로 연결시켜주는 역할을 한다.
6.표준입출력과 File
6.1 표준 입출력 - System.in, System.out, System.err
표준입출력이란 콘솔을 통한 데이터 입력과 콘솔로의 데이터 출력을 의미한다.
System.in 콘솔로부터 데이터를 입력받는데 사용
System.out 콘솔로 데이터를 출력하는데 사용
System.err 콘솔로 데이터를 출력하는데 사용
6.2 표준입출력의 대상변경 - setOut(),setErr(),SetIn()
초기 System.in ,Sytem.out, System.err 의 입출력대상이 콘솔화면이지만 setIn(),setOut(),setErr()를 사용하면 입출력 콘솔 이외 다른 입출력 대상으로 변경하는 것이 가능하다.
메서드 | 설 명 |
static void setOut(PrintStream out) | System.out의 출력을 지정된 PrintStream으로 변경 |
static void setErr(PrintStream err) | System.err의 출력을 지정한 PrintStream으로 변경 |
static void setIn(InputStream in) | System.in의 입력을 지정한 InputStream으로 변경 |
6.4 File
다음은 File의 생성자와 경로에 관련된 메소드이다 .
7. 직렬화
7.1 직열화란
직렬화란 객체를 데이터 스트림으로 만드는 것을 뜻한다.
객체에 저장된 데이터를 스트림에 쓰기위해 연속적인 데이터로 변환하는 것을 뜻한다.
7.2 ObjectInputStream,ObjectOutputStream
직열화에는 ObjectOuputStream을 사용하고 역질려화는 ObjectInputStream을 사용한다.
직렬화가 가능한 클래스를 만들기 위해선 Serializaable 인터페이스를 구현해야 한다.
직렬화
FileOutputStream fos = new FileOutputStream("objectfile.ser")l
objectOutputStream out = new ObjectOutputStream(fos);
out.wirteObject(new UserInfo());
ObejctInputStream과 ObhectOutputStream은 아래와 같은 다양한 메소드도 제공한다.