IO 스트림은 데이터를 입력(input)과 출력(output)에 대한 내용이다. java.io 패키지에서 제공되는 클래스를 활용해 코드를 작성할 수 있다. 스트림은 일방향의 특징을 가지는 데이터 흐름이다. 역방향으로 데이터가 전송될 수 없기 때문에 input, output 을 위한 코드가 따로 존재하게 된다.
입출력의 단위는 크게 바이트, 문자로 나뉜다.
- 바이트는 이미지, 오디오, 동영상 등의 바이너리 파일이 해당된다. 크기는 1byte
- 문자는 한글, 한자 등이 해당된다. 크기는 2byte
입력 | 출력 | ||
바이트 | 최상위 클래스 | InputStream | OutputStream |
하위 클래스 | AudioInputStream ByteArrayInputStream FileInputStream FilterInputStream InputStream ObjectInputStream PipedInputStream SequenceInputStream StringBufferInputStream |
ByteArrayOutputStream FileOutputStream FilterOutputStream ObjectOutputStream OutputStream PipedOutputStream |
|
문자 | 최상위 클래스 | Reader | Writer |
하위 클래스 | BufferedReader CharArrayReader FilterReader InputStreamReader PipedReader StringReader |
BufferedWriter CharArrayWriter FilterWriter OutputStreamWriter PipedWriter PrintWriter StringWriter |
1. InputStream
주요메서드
메서드 | 내용 |
int available() | 스트림에서 읽을 수 있는 바이트 개수 리턴 |
void close() | 스트림 닫고 자원해제 |
abstract int read() | 1 바이트를 읽고 읽은 바이트 리턴 |
int read(byte[] b) | 지정된 배열 크기만큼 읽고 버퍼배열에 저장, 읽은 개수 리턴 |
int read(byte[] b, int off, int len) | -지정된 배열 크기만큼 읽고 버퍼배열에 저장, 읽은 개수 리턴 -읽을 바이트의 시작과 개수를 지정할 수 있음 |
- read()
아래 코드를 보자. 콘솔로 입력한 글자를 바이트로 읽어들이는 코드이다.
스트림 사용시에는 IOException 이 발생하기 때문에 try -catch 문으로 감싸거나 throws 구문이 필요하다.
public class Test01 {
//IOException 이 발생한다. 예외 throws 처리
public static void main(String[] args) throws IOException{
System.out.println("start");
InputStream is = new DataInputStream(System.in);
int a = is.read();
System.out.println("바이트 읽기: "+ a);
byte b = (byte) a;
System.out.println("바이트 char변환 : "+ (char)b);
//스트림 사용한 뒤에는 닫아주기
is.close();
System.out.println("end");
}
}
실행 결과
start 1 바이트 읽기: 49 바이트 char변환 : 1 end |
다른 코드를 보자. 아래는 text 파일의 내용을 읽는 코드이다.
D:/Programming/_temp/ 폴더의 testIn.txt 은 아래와 같다.
public class Test02 {
public static void main(String[] args) throws IOException {
System.out.println("start");
InputStream is = new FileInputStream("D:/Programming/_temp/testIn.txt");
int readByte = 0;
while((readByte = is.read()) != -1){
byte b = (byte) readByte;
System.out.println(readByte+ " char변환 : "+ (char)b);
}
is.close();
System.out.println("end");
}
}
실행 결과
-inputStream은 1바이트씩 끊어서 바이트를 인식한다. 문자는 2바이트이기 때문에 정상적으로 인식되지 않는다.
start 49 char변환 : 1 50 char변환 : 2 51 char변환 : 3 13 char변환 : 10 char변환 : 97 char변환 : a 98 char변환 : b 99 char변환 : c 13 char변환 : 10 char변환 : 234 char변환 : ? 176 char변환 : ? 128 char변환 : ? 235 char변환 : ? 130 char변환 : ? 152 char변환 : ? 235 char변환 : ? 139 char변환 : ? 164 char변환 : ? end |
- read(byte[] b)
public class Test03 {
public static void main(String[] args) throws IOException {
System.out.println("start");
InputStream is = new FileInputStream("D:/Programming/_temp/testIn.txt");
byte[] byteArr = new byte[4];
int readByte = 0;
while((readByte = is.read(byteArr)) != -1){
for(byte b : byteArr){
System.out.println(b + " | "+ (char) b);
}
}
is.close();
System.out.println("end");
}
}
실행 결과
start 49 | 1 50 | 2 51 | 3 13 | 10 | 97 | a 98 | b 99 | c 13 | 10 | -22 | ? -80 | ? -128 | ? -21 | ? -126 | ? -104 | ? -21 | ? -117 | ? -92 | ? -104 | ? end |
- read(byte[] b, int off, int len)
public class Test04 {
public static void main(String[] args) throws IOException {
System.out.println("start");
InputStream is = new FileInputStream("D:/Programming/_temp/testIn.txt");
byte[] byteArr = new byte[4];
int readByte = 0;
while((readByte = is.read(byteArr, 0, byteArr.length)) != -1){
for(byte b : byteArr){
System.out.println(b + " | "+ (char) b);
}
}
is.close();
System.out.println("end");
}
}
실행 결과
start 49 | 1 50 | 2 51 | 3 13 | 10 | 97 | a 98 | b 99 | c 13 | 10 | -22 | ? -80 | ? -128 | ? -21 | ? -126 | ? -104 | ? -21 | ? -117 | ? -92 | ? -104 | ? end |
2. OutputStream
주요 메서드
메서드 | 내용 |
void close() | 스트림 닫고 자원해제 |
void flush() | 버퍼를 비우기. 버퍼내의 모든 데이터 출력 |
void write(byte[] b) | 바이트배열 출력하기 |
void write(byte[] b, int off, int len) | 바이트배열 출력하기(시작과 끝 설정) |
abstract void write(int b) | 바이트 1개를 출력하기 |
- write(int b)
public class Test01 {
public static void main(String[] args) throws IOException {
System.out.println("start");
OutputStream os = new FileOutputStream("D:/Programming/_temp/testOut.txt");
byte[] sendDate = "ABC123가나".getBytes();
for(byte b: sendDate){
os.write(b);
}
os.flush();
os.close();
System.out.println("end");
}
}
실행 결과 - 콘솔
start end |
실행 결과 - testOut.txt
ABC123가나 |
- write(byte[] b)
public class Test02 {
public static void main(String[] args) throws IOException {
OutputStream os = new FileOutputStream("D:/Programming/_temp/testOut.txt");
byte[] sendDate = "ABC234홍길동".getBytes();
os.write(sendDate);
os.flush();
os.close();
}
}
실행 결과 - testOut.txt
ABC234홍길동 |
- write(byte[] b, int off, int len)
public class Test03 {
public static void main(String[] args) throws IOException {
OutputStream os = new FileOutputStream("D:/Programming/_temp/testOut.txt");
byte[] sendDate = "ABC12345".getBytes();
//write(byte[] b) 과 동일한 결과가 나온다
os.write(sendDate, 0, sendDate.length);
os.flush();
os.close();
}
}
실행 결과 - testOut.txt
ABC12345 |
- 바이트 배열의 시작과 끝을 설정하기
public class Test04 {
public static void main(String[] args) throws IOException {
OutputStream os = new FileOutputStream("D:/Programming/_temp/testOut.txt");
byte[] sendDate = "ABC12345".getBytes();
os.write(sendDate, 3, 3);
os.flush();
os.close();
}
}
실행 결과 - testOut.txt
123 |
3. Reader
주요 메서드
메서드 | 내용 |
int read() | 문자 한개 읽기. 읽은 문자값을 유니코드 값으로 리턴한다 읽은 값이 없으면 -1 리턴 |
int read(char[] cbuf) | 문자를 하나씩 읽어 cbuf 에 저장하고 읽은 문자개수 리턴 |
abstract int read(char[] b, int start, int length) | 문자를 length 만큼 읽기, cbuf의 start 부터 저장. 읽은 문자개수 리턴 |
abstract void close() | 스트림 닫고 자원해제 |
아래 코드를 보자
public class Test03 {
public static void main(String[] args) throws IOException {
String fileOut = "D:/Programming/_temp/testWrite.txt";
Writer fw = new FileWriter(fileOut);
char[] charArr = "123abc홍길동".toCharArray();
fw.write(charArr);
fw.flush();
fw.close();
}
}
실행 결과
-지정한 위치에 파일이 생성됨
4. Writer
주요 메서드 | 내용 |
abstract void write(int c) | int 값을 char로 변환해서 쓰기 |
void write(char[] cbuf) | char 배열 내용 쓰기 |
abstract void write(char[] cbuf, int start, int length) | char 배열 내용 쓰기. start부터 length 만큼 |
void write(String str) | str 쓰기 |
abstract void flush() | 버퍼가 가득차 있지 않아도 버퍼 비우기 |
abstract void close() | 스트림 닫고 자원해제 |
아래 코드를 보자
public class Test01 {
public static void main(String[] args) throws IOException {
String fileName = "D:/Programming/_temp/test01.txt";
Writer fw = new FileWriter(fileName);
String message = "hello 홍길동";
fw.write(message);
fw.close();
}
}
실행 결과
-해당 경로에 파일이 생성된다
5. Console 클래스
콘솔로 문자열을 입력받아 처리할 수 있는 클래스이다.
System 정적메서드로 콘솔 호출하기
Console console = System.console();
System.in 호출해 InputStream으로 받기
public class Test01 {
public static void main(String[] args) throws IOException {
System.out.println("start");
InputStream istream = System.in;
int a;
while((a = istream.read()) != -1){
if(a == 13 || a == 10) { break; } //캐리지 리턴 걸러내기
System.out.println((char) a);
}
System.out.println("end");
}
}
'Java > 기본' 카테고리의 다른 글
[Java] IO스트림 사용하기 - 객체 직렬화(Serialize) (0) | 2021.07.25 |
---|---|
[Java] IO스트림 사용하기 - 스트림 연결하기(Stream chaining) (0) | 2021.07.25 |
[Java] 스트림(Stream) 익히기 (0) | 2021.07.17 |
[Java] 람다식(Lambda) 익히기 (0) | 2021.07.16 |
[Java] 스레드(Thread) 활용하기 - 데몬스레드, 스레드 그룹, 스레드 풀 (0) | 2021.07.08 |