안녕하세요, 코린이의 코딩 학습기 채니 입니다.
개인 포스팅용으로 내용에 오류 및 잘못된 정보가 있을 수 있습니다.
자바 입출력(java IO)
- 프로그램을 기준으로 외부로부터 데이터가 들어오는 입력(input)과 프로그램에서 외부로 나가는 출력(output)으로 구성
- 입력의 대상 : 키보드/마우스/파일/네트워크 등
- 출력의 대상 : 화면/프린터/파일/네트워크/콘솔 등
자바 입출력 종류
① byte 단위 입출력
- 송수신하고자 하는 데이터를 byte 단위로 쪼개 보내고 받는 것
② char 단위 입출력
- 텍스트 전송에 특화된 방법
Reader 클래스의 자식 클래스에는 FileReader, BufferedReader, InputStreamReader가 있고,
Writer 클래스의 자식 클래스에는 FileWriter, BufferedWriter, OutputStreamWriter, printWriter가 있습니다.
InputStreamReader와 OutputStreamReader 클래스는 byte 단위의 데이터 입출력 클래스인 InputStream과 OutputStream을 char 단위의 입출력 클래스인 Reader와 Writer로 변환하는 클래스입니다.
Reader의 주요 메소드
int skip(long n) | n개의 char 스킵하기(실제 스킵된 char 개수를 리턴) |
int read() | int(4byte)의 하위 2byte에 읽은 데이터를 저장해 리턴 |
int read(char[] cbuf) | 읽은 데이터를 char[] cbuf에 저장하고, 읽은 char개수를 리턴 |
abstract int read(char[] cbuf, int off, int len) | len 개수만큼 읽은 데이터를 char[] cbuf의 off 위치부터 저장 (추상 메소드) |
abstract void close() | Reader의 자원 반환 |
Writer의 주요 메소드
abstract void flush() | 메모리 버퍼에 저장된 데이터 내보내기(실제 출력 수행) (추상 메소드) |
void write(int c) | int(4byte)의 하위 2byte를 메모리 버퍼에 출력 |
void write(char[] cbuf) | 매개변수로 넘겨진 char[] cbuf 데이터를 메모리 버퍼에 출력 |
void write(String str) | 매개변수로 넘겨진 String 값을 메모리 버퍼에 출력 |
void write(String str, int off, int len) | str의 off 위치에서부터 len 개수를 읽어 메모리 버퍼에 출력 |
abstract void write(char[] cbuf, int off, int len) | char[]의 off 위치에서부터 len 개수를 읽어 출력(추상 메소드) |
abstract void close() | Writer의 자원 반환(추상 메소드) |
문자 기반 입출력 스트림
☞ FileReader
//객체 생성 방법 1) (String)
FileReader fr1 = new FileReader("files/helloworld.txt");
//객체 생성 방법 2) (File)
File file = new File("files/helloworld.txt");
FileReader fr2 = new FileReader(file);
FileReader의 객체를 생성하는 방법으로 2가지가 있습니다.
FileReader(String name) | 매개변수로 넘어온 name 위치의 파일을 읽기 위한 Reader 생성 |
FileReader(File file) | 매개변수로 넘어온 file을 읽기 위한 Reader 생성 |
파일 읽어오기
//helloworld.txt
1234567890
abcdefg
가나다라마바
files폴더 하위에 helloworld.txt 파일을 생성하여 파일을 읽어와보았습니다.
FileReader fr = null;
try {
fr = new FileReader("files/helloworld.txt");
int data = 0; //읽어온 값
while((data = fr.read()) != -1) {
System.out.print((char)data + " ");
}
} catch(IOException e) {
e.printStackTrace();
} finally {
try {
fr.close();
} catch(IOException e) {
e.printStackTrace();
}
}
@콘솔출력값
1 2 3 4 5 6 7 8 9 0
a b c d e f g
가 나 다 라 마 바
char 단위 입출력을 수행한다는 것은 문자열에 영문만 있든, 한글 등의 다국어 문자가 포함 되어 있든 차이가 없습니다.
char 타입 자체가 다국어 문자를 저장할 수 있는 유니코드이기 때문입니다.
따라서 한글 역시 깨지지 않고 정상적으로 출력 된 것을 확인할 수 있습니다.
read() 메소드를 통해 읽어온 값을 반환하여 data에 담아 출력하였습니다.
또한, 모든 작업이 끝나면 사용했단 FileReader 자원을 close() 메소드를 이용해 반납하였습니다.
이렇게 되면 FileReader 객체는 더 이상 사용할 수 없으며, 파일과의 연결도 종료됩니다.
반드시 사용 후 반납해야 하기 때문에 finally 절에서 로직을 짰습니다.
☞ FileWriter
//객체 생성 방법 1) (String)
FileWriter fw1 = new FileWriter("files/helloworld.txt");
//객체 생성 방법 2) (String, append)
FileWriter fw2 = new FileWriter("files/helloworld.txt", true);
//객체 생성 방법 3) (File)
File file1 = new File("files/helloworld.txt");
FileWriter fw3 = new FileWriter(file1);
//객체 생성 방법 4) (File, append)
File file2 = new File("files/helloworld.txt");
FileWriter fw4 = new FileWriter(file2);
FileWriter의 객체를 생성하는 방법으로 4가지가 있습니다.
FileWriter(String name) | 매개변수로 넘어온 name 위치의 파일을 쓰기 위한 Writer 생성 append = true일 때 이어쓰기 append = false일 때 덮어쓰기(default = false) |
FileWriter(String name, boolean append) | |
FileWriter(File file) | 매개변수로 넘어온 file을 쓰기 위한 Writer 생성 append = true일 때 이어쓰기 append = false일 때 덮어쓰기(default = false) |
FileWriter(File file, boolean append) |
파일 출력하기
FileReader fr = null;
FileWriter fw = null;
try {
fr = new FileReader("files/helloworld.txt");
fw = new FileWriter("files/copy.txt");
int data = 0;
while((data = fr.read()) != -1) {
System.out.print((char)data + " "); //콘솔 출력
fw.write(data);
}
} catch(IOException e) {
e.printStackTrace();
} finally {
try {
fr.close();
} catch(IOException e) {
e.printStackTrace();
}
try {
fw.close();
} catch(IOException e) {
e.printStackTrace();
}
}
@콘솔출력값
1 2 3 4 5 6 7 8 9 0
a b c d e f g
가 나 다 라 마 바
마찬가지로 사용한 FileWriter 자원을 close()메소드를 이용해 반납하여야 하는데,
fr.close() 가 있는 try절에 한 번에 묶어서 예외처리를 하면 좋겠지만 fr.close() 수행 시 IOException 이 발생하게 된다면 하위 구문은 실행하지 않은 채로 catch(){} 블록으로 넘어가기 때문에 FileWriter 자원에 대한 반납이 이루어지지 않게 됩니다.
따라서 다소 번거롭지만 try-catch문을 하나 더 사용하여 자원 반납을 해주었습니다.
만일 파일이 존재하는 경우 덮어쓰기/이어쓰기가 되고, 파일이 존재하지 않은 경우에는 파일을 새로 생성합니다.
"files/copy.txt" 파일은 존재하지 않기 때문에 "files/copy.txt" 파일이 새로 생성되었고, 기존 "files/helloworld.txt"의 내용을 읽어와 "files/copy.txt"파일에 썼기 때문에 동일한 내용의 파일이 생성되었습니다.
//copy.txt
1234567890
abcdefg
가나다라마바
입출력 실습
FileReader fr = null;
FileWriter fw = null;
try {
fw = new FileWriter("files/test.txt");
fw.write("안녕하세요\n");
fw.write("Hello");
fw.write("\r");
fw.write("\n");
fw.write("감사합니당", 2, 3);
fw.flush();
fr = new FileReader("files/test.txt");
int data = 0;
while((data = fr.read()) != -1) {
System.out.print((char)data);
}
} catch(IOException e) {
e.printStackTrace();
} finally {
try {
fr.close();
} catch(IOException e) {
e.printStackTrace();
}
try {
fw.close();
} catch(IOException e) {
e.printStackTrace();
}
}
@콘솔출력값
안녕하세요
Hello
합니당
//test.txt
안녕하세요
Hello
합니당