본문 바로가기

프로그래밍/JAVA

[JAVA 이론] 입출력 I/O

자바에서의 입출력

입출력이란?

I/O란 Input과 Output의 약자로 입력과 출력, 간단히 줄여서 입출력이라고 한다. 입출력은 컴퓨터 내부 또는 외부의 장치와 프로그램간의 데이터를 주고받는 것을 말한다.

 

스트림

- 자바에서 입출력을 수행할때 데이터를 운반하는데 사용되는 연결 통로이다.

- 스트림은 단방향 통신만 가능하다.

- 스트림은 먼저 보낸 데이터를 먼저 받게 되어 있으며 중간에 건너뜀 없이 연속적으로 데이터를 주고 받는다.(FIFO)

- 인터페이스 스트림과 용어는 같지만 다른 개념이다.

 

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

스트림은 바이트단위로 데이터를 전송하며 입출력 대상에 따라 다음과 같은 입출력스트림이 있다.

입력스트림 출력스트림 입출력 대상의 종류
FileInputStream FileOutputStream 파일
ByteArrayInputStream ByteArrayOutputStream 메모리(byte배열)
PipedInputStream PipedOutputStream 프로세스(프로세스간의 통신)
AudioInputStream AudioOutputStream 오디오장치

이들은 모두 InputStream, OutputStream의 자손들이며, 각각 읽고 쓰는데 필요한 추상메서드를 자신에 맞게 구현해 놓았다.

 

InputStream OutputStream
abstract int read() abstract void write(int b)
int read(byte[] b) void write(byte[] b)
int read(bye[] b, int off, int len) void wrtie(byte[], int off, int len)

InputStream의 read()와 OutputStream의 write(int b)는 입출력의 대상에 따라 읽고 쓰는 방법이 다를 것이기 때문에 상황에 알맞게 구현할 수 있도록 추상메서드로 정의되어 있다. read()와 write(int b)를 제외한 나머지 메서드들도 read()와 write(int b)를 이용해서 구현되어 있다.

 

보조 스트림

보조스트림은 실제 데이터를 주고받는 스트림이 아니기 때문에 데이터를 입출력할 수 있는 기능은 없지만, 스트림의 기능을 향상시키거나 새로운 기능을 추가 할 수 있다.

/* 예시 */

//먼저 기반스트림을 생성한다.
FileInputStream fis = new FileInputStream("test.txt");

//기반스트림을 이용해서 보조스트림을 생성한다.
BufferedInputStream bis =new BufferedInputStream(fis);

//보조스트림인 BufferedInputStream으로부터 데이터를 읽는다. 실제로는 FileInputStream이 수행
bis.read();
입력 츨력 설명
FilterInputStream FilterOutputStream 필터를 이용한 입출력 처리
BufferedInputStream BufferedOutputStream 버퍼를 이용한 입출력 성능향상
DataInputStream DataOutputStream 기본형 단위(Primitive type)로 데이터를 처리하는 기능
SequenceInputStream 없음 두 개의 스트림을 하나로 연결
LineNumberInputStream 없음 익어 온 데이터의 라인 번호를 카운트(JDK 1.1부터 LineNumberReader로 대체)
ObjectInputStream ObjectOutoutStream 데이터를 객체단위로 읽고 쓰는데 사용
주로 파일을 이용하며 객체 직렬화와 관련 있음
없음 PrintStream 버퍼를 이용하며, 추가적인 print관련 기능
(print, printf, println메서드)
pushbackInputStream 없음 버퍼를 이용해서 읽어 온 데이터를 다시 되돌리는 기능
(unread, push back to buffer)

 

문자기반 스트림 - Reader, Writer

자바에서는 한 문자를 의미하는 char형이 1 byte가 아니라 2 byte이기 때문에 바이트기반의 스트림으로는 문자를 처리하는 데는 어려움이 있다. 이 점을 보완하기 위해서 문자기반의 스트림이 제공된다.

InputStream            ->            Reader

OutputStream        ->            Writer

 

- 바이트기반 스트림과 문자기반 스트림의 비교

바이트기반 스트림 문자기반 스트림
FileInputStream
FileOutputStream
FileReader
FileWriter
ByteArrayInputStream
ByteArrayOutputStream
CharArrayReader
CharArrayWriter
PipedInputStream
PipedOutputStream
PipedReader
PipedWriter
StringBufferInputStream(deprecated)
StringBufferOutputStream(deprecated)
StringReader
StringWriter

 

-바이트기반 스트림과 문자기반 스트림의 읽고 쓰는 메서드 비교

InputStream Reader
abstract int read()
int read(byte[] b)
int read(byte[] b, int off, int len)
int read()
int read(char[] cbuf)
abstract int read(char[] cbuf, int off, int len)
OutputStream Writer
abstract void writer(int b)
void writer(byte[] b)
void write(byte[] b, int off, int len)
void write(int c)
void write(char[] cbuf)
abstract void write(char[] cbuf, int off, int len)
void write(String str)
void write(String str, int off, int len)

 

- 바이트기반 보조스트림과 문자기반 보조스트림

바이트기반 보조스트림 문자기반 보조스트림
BufferedInputStream
BufferedOutputStream
BufferedReader
BufferedWriter
FilterInputStream
FilterOutputStream
FilterReader
FilterWriter
LineNumberInputStream LineNumberReader
PrintStream printWriter
PushbackInputStream PushbackReader

 

바이트기반 스트림

1. 바이트기반 스트림

1) InputStream과 OutputStream

- InputStream의 메서드

메서드명 설명
int available() 스트림으로부터 읽어 올 수 있는 데이터의 크기를 반환한다.
void close() 스트림을 닫음으로써 사용하고 있던 자원을 반환한다.
void mark(int readlimit) 현재위치를 표시해 놓는다. 후에 reset()에 의해서 표시해 놓은 위치로 다시 돌아갈 수 있다. 
readmit은 되돌아갈 수 있는 byte의 수이다.
boolean markSupported() mark()와 reset()을 지원하는지를 알려 준다. mark()와 reset()기능을 지원하는 것은 선택적이므로, mark()와 reset()을 사용하기 전에 markSupported()를 호출해서 지원여부를 확인해야 한다.
abstract int read() 1byte를 읽어 온다(0~255사이의 값). 더 이상 읽어 올 데이터가 없으면 -1을 반환한다.
abstract메서들서 InputStream의 자손들은 자신의 사황에 알맞게 구현해야한다.
int read(byte[] b) 배열 b의 크기만큼 읽어서 배열을 채우고 읽어 온 데이터의 수를 반환한다. 반환하는 값은 항상 배열의 크기보다 작거나 같다.
int read(byte[], int off, int len) 최대 len개의 byte를 읽어서, 배열 b의 지정된 위치(off)부터 저장한다. 실제로 읽어 올 수 있는 데이터가 len개보다 적을 수도 있다.)
void reset() 스트림에서의 ㅟ치를 마지막으로 mark()이 호출되었던 위치로 되돌린다.
long skip(long n) 스트림에서 주어진 길이(n)만큼을 건너뛴다.

- OutputStream의 메서드

메서드명 설명
void close() 입력소스를 닫음으로써 사용하고 있던 자원을 반환한다.
void flush() 스트림의 버퍼에 있는 모든 내용을 출력소스에 쓴다.
abstract void write(int b) 주어진 값을 출력소스에 쓴다.
void write(byte[] b) 주어진 배열 b에 저장된 모든 내용을 출력소스에 쓴다.
void write(byte[] b, int off, int len) 주어진 배열 b에 저장된 내용 중에서 off번째부터 len개 만큼만을 읽어서 출력소스에 쓴다.

프로그램이 종료될 때, 사용하고 닫지 않은 스트림을  JVM이 자동적으로 닫아 주기는 하지만, 스트림을 사용해서 모든 작업을 마치고 난 후에는 close를 호출해서 반드시 닫아 주어야한다. 메모리를 사용하는 스트림과 표준 입출력 스트림은 닫아 주지 않아도 된다.

 

2) byteArrayInputStream과 ByteArrayOutputStream

메모리, 즉 바이트배열에 데이터를 입출력 하는데 사용되는 스트림이다. 주로 다른 곳에 입출력하기 전에 데이터를 임시로 바이트배열에 담아서 변환 등의 작업을 하는데 사용된다.

 

3) FileInputStream과 FileOutputStream

- FileInputStream과 FileOutputstream의 생성자

생성자 설명
FileInputStream(String name) 지정된 파일이름(name)을 가진 실제 파일과 연결된 FileInputStream을 생성.
FileInputStream(File file) 파일의 이름이 String이 아닌 File인스턴스로 지정해주어야 하는 점을 제외하고 FileInputStream(String name)와 같다.
FileInputStream(FileDescriptor fdObj) 파일 디스크립터(fdObj)로 FileInputStream을 생성한다.
FileOutputStream(String name) 지정된 파일이름(name)을 가진 파일과의 연결된 FileOutputStream을 생성
FileOutputStream(String name, boolean append) 지정된 파일이름(name)을 가진 실제 파일과 연결된 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) 파일 디스크립터(fdObj)로 FileOutputStream을 생성한다.

 

2. 바이트기반 보조스트림

1) FilterInputStream과 FilterOutputStream

FilterInputStream과 FilterOutputStream은 InputStream/OutputStream의 자손이면서 모든 보조스틀미의 조상이다.

FilterInputStream과 FilterOutputStream은 상속을 통해 원하는 작업을 수행하도록 읽고 쓰는 메서드를 오버라이딩해야 한다.

FilterInputStream 생성자는 접근 제어자가 protected이기 때문에 FilterInputStream의 인스턴스를 생성해서 사용할 수 없고 상속을 통해서 오버라이딩 되어야 한다.

//생성자
protected FilterInputStream(InputStream in)
public    FilterStream(OutputStream out)

//FilterInputStream의 자손
BufferedInputStream, DataInputStream, PushbackInputStream 등

//FilterOutputStream의 자손
BufferedOutputStream, DataOutputStream, PrintStream 등

 

2) BufferedInputStream과 BufferedOutputStream

BufferedInputStream/BufferedOutputStream은 스트림의 입출력 효율을 높이기 위해 버퍼를 사용하는 보조스트림이다. 한 바이트씩 입출력하는 것 보다는 버퍼(바이트배열)를 이용해서 한 번에 여러 바이트를 입출력하는 것이 빠르기 때문에 대부분의 입출력 작업에 사용된다.

- BufferedInputStream의 생성자

생성자 설명
BufferedInputStream(InputStream in, int size) 주어진 InputStream인스턴스를 입력소스(input source)로 하며 지정된 크기(byte단위)의 버퍼를 갖는 BufferedInputStream인스턴스를 생성한다.
BufferedInputStream(InputStream in) 주어진 InputStream인스턴스를 입력소스(input source)로 하며 버퍼의 크기를 지정해주지 않으므로 기본적으로 8192 byte 크기의 버퍼를 갖게 된다.

- BufferedOutputStream의 생성자와 메서드

메서드/생성자 설명
BufferedOutputStream(OutputStream out, int size) 주어진 OutputStream인스턴스를 출력소스(output source)로하며 지정된 크기(단위byte)의 버퍼를 갖는 BufferedOutputStream인스턴스를 생성.
BufferedOutputStream(OutputStream out) 주어진 OutputStream인스턴스를 출력소스(output source)로하며 버퍼의 크기를 지정해주지 않으므로 기본적으로 8192byte 크기의 버퍼를 갖게 됨
flush() 버퍼의 모든 내용을 출력소스에 출력한 다음, 버퍼를 비운다.
close() flush()를 호출해서 버퍼의 모든 내용을 출력소스에 출력하고, BufferedOutputStream인스턴스가 사용하던 모든 자원을 반환한다.

 

3) DataInputStream과 DataOutputStream

DataInputStream은 DataInput인테페이스를 DataOutputStream은 DataOutput인터페이스를 구현하였기 때문에, 데이터를 읽고 쓰는데 있어서 byte단위가 아닌, 8가지 기본 자료형의 단위로 읽고 쓸 수 있다는 장점이 있다.

DataOutputStream이 출력하는 형식은 각 기본 자료형 값을 16진수로 표현하여 저장한다.

- DataInputStream의 생성자 메서드(표 삽입 필요)

- DataOutputStream의 생성자와 메서드(표 삽입 필요)

 

 

문자기반 스트림

입출력이란?

I/O란 Input과 Outp

 

 표준입출력과 File

입출력이란?

I/O란 Input과 Outp

 

직렬화

입출력이란?

I/O란 Input과 Outp

'프로그래밍 > JAVA' 카테고리의 다른 글

[JAVA 이론] 네트워킹  (0) 2022.08.15
[JAVA 이론] 람다와 스트림  (0) 2022.06.22
[JAVA 이론] 쓰레드  (0) 2022.03.16
[JAVA 이론] Generics, Enumeration, Annotation  (0) 2022.03.13
[JAVA 이론] Collections Framework  (0) 2022.02.27