오늘은 좋아하는 IO를 다루는 날이다. 졸리더라도 참고 본방사수하자!
Java에는 Standard IO와 NIO(New IO)가 있다. NIO는 잘은 모르지만 기존의 표준 IO를 개선하기 위해 생겨났을 거라고 추측한다. NIO는 asynchronous + non-blocking IO가 가능하다.
표준 IO의 Stream은 전통적인 Unix 방식을 따른 것이다. Unix 이전에는 IO를 수행하기 위해서 개발자가 HW / OS 각각마다 직접 장치를 연결하고 제어해야 했다. 당시의 입출력 장치는 주로 테이프, 전동 타지기 등이었는데, Unix는 표준 파일 시스템 아래서 이를 파일과 스트림으로 추상화하였다. 기존에는 IO를 수행하기 위해서, 물리적인 디스크의 트랙당 섹터수와, 섹터의 크기와 같은 특성을 알고 이를 직접 제어한 반면 스트림으로 추상화한 IO system call은 매우 간결해졌다고 한다.
fd = create(file)
fd = open(file)
read(fd, buf, count)
write(fd, buf, count)
lseek(fd, pos) //포인터 이동, FastForward 또는 Rewind에 해당
Unix와 함께 개발된 C언어는 언어에서 표준 IO를 제공하지 않는다. 별도로 제공되는 라이브러리를 이용해서 IO가 제공되는데 C언어 입출력 함수도 유닉스 시스템콜을 1:1로 Wrapping한 것에 가깝다.
또한 자바의 IO도 기본적으로는 기술한 시스템콜과 거의 같은 방식으로 사용할 수 있다.
보통 스트림을 흐르는 물에 비유하는데, 가장 비슷한 것은 소니 워크맨같은 테이프 레코더 같다. 읽기는 테이프의 Play, 쓰기는 테이프의 Rec와 유사하다.
스트림은 단뱡향이고 동시에 읽기와 쓰기를 할 수 없다. 읽기와 쓰기를 함께 하려면 파일을 열어 스트림을 두 개 생성해야 한다.
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class CopyBytes {
public static void main(String[] args) throws IOException {
FileInputStream in = null;
FileOutputStream out = null;
try {
in = new FileInputStream("xanadu.txt");
out = new FileOutputStream("outagain.txt");
int c;
while ((c = in.read()) != -1) {
out.write(c);
}
} finally {
if (in != null) {
in.close();
}
if (out != null) {
out.close();
}
}
}
}
BufferedInputStream : 성능 개선
DataInputStream: 프리미티브 기반 제어
SequenceInputStream: 두 개의 스트림을 하나로 연결, 입력 전용
LineNumberInputStream: 줄 번호 카운트
ObjectInputStream: 객체 단위 읽기
PrintStream: print() 관련 기능 제공
PushbackInputStream: 읽기 되돌리기 가능
FileReader / Writer
CharArrayReader / Writer
PipedReader / Writer
StringReader / Writer
BufferedReader / Writer
LineNumberReader
PrintWriter
PushbackReader
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
public class BufferedReaderFileRead {
public static void main(String[] args) throws IOException {
String line = null;
System.out.println("Reading fom file");
BufferedReader reader =
new BufferedReader(new FileReader(System.getProperty("user.dir") +
"test.txt"));
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
System.out.println("Finished reading file");
}
reader.close();
}