📌IO 패키지 소개
프로그램에선 데이터를 외부에서 읽고 다시 외부로 출력하는 작업이 빈번히 일어난다. 데이터는 사용자로부터 키보드를 통해 입력될 수도 있고, 파일 또는 네트워크로부터 입력될 수도 있다. 데이터는 반대로 모니터로 출력될 수도 있고, 파일로 출력되어 저장될 수도 있으며 네트워크로 출력되어 전송될 수 있다. Java에서 데이터는 Stream을 통해 입출력되므로 스트림의 특징을 잘 이해해야 한다.
📌입력 스트림과 출력 스트림 (InputStream & OutputStream)
프로그램이 데이터를 입력받을 때는 입력 스트림(InputStream)이라 부르고,
프로그램이 데이터를 보낼 때에는 출력 스트림(OutputStream)이라 부른다.
프로그램이 네트워크상의 다른 프로그램과 데이터 교환을 하기 위해서는 양쪽 모두 입력 스트림과 출력 스트림이 따로 필요하다. 그 이유는 스트림은 단방향이므로 하나의 스트림으로 입력과 출력을 모두 할 수 없기 때문이다.
Java의 기본적인 데이터 입출력(IO) API는 java.io 패키지에서 제공하고 있다.
java.io 패키지의 주요 클래스 | 설명 |
File | 파일 시스템의 파일 정보를 얻기 위한 클래스 |
Console | 콘솔로부터 문자를 입출력하기 위한 클래스 |
InputStream/OutputStream | 바이트 단위 입출력을 위한 최상위 입출력 스트림 클래스 |
FileInputStream/FileOutputStream DataInputStream/DataOutputStream ObjectInputStream/ObjectOutputStream PrintStream BufferedInputStream/BufferedOutputStream |
바이트 단위 입출력을 위한 하위 스트림 클래스 |
Reader/Writer | 문자 단위 입출력을 위한 최상위 입출력 스트림 클래스 |
FileReader/FileWriter InputStreamReader/OutputStreamWriter PrintWriter BufferedReader/BufferedWriter |
문자 단위 입출력을 위한 하위 스트림 클래스 |
스트림 클래스는 크게 두 종류로 구분된다. 하나는 byte 기반 스트림이고, 다른 하나는 문자 기반 스트림이다.
byte 기반 스트림은 그림, 멀티미디어, 문자 등 모든 종류의 데이터를 받고 보낼 수 있으며, 문자 기반 스트림은 오로지 문자만 받고 보낼 수 있도록 특화되어 있다.
구분 | 바이트 기반 스트림 | 문자 기반 스트림 | ||
입력 스트림 | 출력 스트림 | 입력 스트림 | 출력 스트림 | |
최상위 클래스 | InputStream | OutputStream | Reader | Writer |
하위 클래스 (ex) |
XXXInputStream (FileInputStream) |
XXXOutputStream (FileOutputStream) |
XXXReader (FileReader) |
XXXWriter (FileWriter) |
InputStream
read() 메소드
read() 메소드는 입력 스트림으로부터 1바이트를 읽고 4바이트 int 타입으로 리턴한다. 따라서 리턴된 4바이트 중 끝의 1바이트에만 데이터가 들어 있다. 예를 들어 입력 스트림에서 5개의 바이트가 들어온다면 read() 메소드로 1바이트씩 번 읽을 수 있다. 더 이상 입력 스트림으로부터 바이트를 읽을 수 없다면 read() 메소드는 -1을 리턴한다. 이를 이용하여 읽을 수 있는 마지막 바이트까지 루프를 돌며 한 바이트씩 읽을 수 있다.
InputStream is = new FileInputStream("파일경로");
int readByte;
while((readByte=is.read()) != -1 ) {...}
read(byte[ ] b) 메소드
read(byte[ ] b) 메소드는 입력 스트림으로부터 매개값으로 주어진 바이트 배열의 길이만큼 바이트를 읽고 배열에 저장한다. 그리고 읽은 바이트 수를 리턴한다. 실제로 읽은 바이트 수가 배열의 길이보다 작을 경우 읽은 수만큼만 리턴한다. 역시 입력 스트림으로부터 바이트를 더 이상 읽을 수 없다면 -1을 리턴하는데, 이 것을 이용하면 읽을 수 있는 마지막 바이트까지 루프를 돌며 읽을 수 있다.
InputStream is = new FileInputStream("파일경로");
int readByteNo;
byte[] readBytes = new byte[100];
while((readBtyeNo=is.read(readBytes)) != -1) {...}
예를 들어 입력 스트림에서 240개의 바이트가 들어온다면 위와 같이 길이 100인 바이트 배열로 세 번 읽을 수 있다.
첫 번째 읽을 경우: 100 바이트 읽음
두 번째 읽을 경우: 100 바이트 읽음
세 번째 읽을 경우: 40 바이트 읽음
read(byte[ ] b, int off, int len) 메소드
입력 스트림으로부터 len 개의 바이트만큼 읽고, 매개값으로 주어진 바이트 배열 b[off]부터 len개 까지 저장한다. 그리고 읽은 바이트 수인 len개를 리턴한다. 이 역시 입력 스트림으로부터 바이트를 더 이상 읽을 수 없다면 -1을 리턴한다. read(byte[ ] b)와의 차이점은 한 번에 읽어들이는 바이트 수를 len 매개값으로 조절할 수 있고, 배열에서 저장이 시작되는 인덱스를 지정할 수 있다. 만약 off를 0으로, len을 배열의 길이로 준다면 read(byte[ ] b)와 동일하다.
close() 메소드
InputStream을 더 이상 사용하지 않을 경우 close()메소드를 호출해서 InputStream에서 사용했던 시스템 자원을 풀어준다.
OutputStream
write(byte[ ] b) 메소드
매개값으로 주어진 바이트 배열의 모든 바이트를 출력 스트림으로 보낸다.
OutputStream os = new FileOutputStream("파일경로");
byte[] data = "ABC".getBytes();
os.write(data); //"ABC" 모두 출력
write(byte[ ] b, int off, int len) 메소드
b[off]부터 len개의 바이트를 출력 스트림으로 보낸다.
OutputStream os = new FileOutputStream("파일경로");
byte[] data = "ABC".getBytes();
os.write(data, 1, 2); //"BC" 모두 출력
flush()와 close() 메소드
출력 스트림은 내부에 작은 버퍼(buffer)가 있어서 데이터가 출력되기 전에 버퍼가 쌓여있다가 순서대로 출력된다. flush() 메소드는 버퍼에 잔류하고 있는 데이터를 모두 출력시키고 버퍼를 비우는 역할을 한다. 프로그램에서 더 이상 출력할 데이터가 없다면 flush() 메소드를 마지막으로 호출하여 버퍼를 잔류하는 모든 데이터가 출력되도록 해야 한다. OutputStream을 더 이상 사용하지 않을 경우에는 close() 메소드를 호출해서 OutputStream에서 사용했던 시스템 자원을 풀어준다.
Reader
read() 메소드
입력 스트림으로부터 한 개의 문자(2 byte)를 읽고 4바이트 int 타입으로 리턴한다. 따라서 리턴된 4바이트 중 끝에 있는 2바이트에 문자 데이터가 들어 있다. 예를 들어 입력 스트림에서 2개의 문자(총 4 바이트)가 들어온다면 read()메소드로 한 문자씩 두 번 읽을 수 있다. InputStream과 마찬가지로 더 이상 입력 스트림으로부터 문자를 읽을 수 없다면 read() 메소드는 -1을 리턴한다.
Reader reader = new FileReader("파일경로");
int readData;
while((readData=reader.read()) != -1){
char charData = (char) readData;
}
read(char[ ] cbuf) 메소드
위 설명 + InputStream 형식과 유사함.
read(char[ ] cbuf, int off, int len) 메소드
위 설명 + InputStream 형식과 유사함.
close() 메소드
위 설명 + InputStream 형식과 유사함.
Writer
write(int c) 메소드
매개 변수로 주어진 int 값에서 끝에 있는 2바이트(한 개의 문자)만 출력 스트림으로 보낸다.
write(char[ ] cbuf) 메소드
매개값으로 주어진 char[ ] 배열의 모든 문자를 출력 스트림으로 보낸다.
Write writer = new FileWriter("파일 경로");
char[] data = "홍길동".toCharArray();
writer.write(data); //"홍길동" 모두 출력
write(byte[ ] b, int off, int len) 메소드
c[off]부터 len 개의 문자를 출력스트림으로 보낸다.
write(String str)와 write(String str, int off, int len) 메소드
Writer는 문자열을 좀 더 쉽게 보내기 위해서 write(String str)와 write(String str, int off, int len) 메소드를 제공한다. write(String str)은 문자열 전체를 출력 스트림으로 보내고, write(String str, int off, int len)은 주어진 문자열 off 순번부터 len개 까지의 문자를 보낸다.
Writer writer = new FileWriter("파일경로");
String data = "안녕 여승철";
writer.write(data);
writer.flush();
writer.close();
'Java' 카테고리의 다른 글
[Java] NIO 기반 입출력 - (1)NIO란? (0) | 2022.06.07 |
---|---|
[Java] TCP 네트워킹 - (4)스레드 병렬 처리 (0) | 2022.06.06 |
BufferedReader / BufferWriter (0) | 2022.04.01 |
[Java] 스트림(stream) (0) | 2021.08.07 |
[Java] 람다식 (Lambda expression) (0) | 2021.08.07 |