문자기반 스트림
Reader&Writer
byte 배열대신 char 배열을 사용한다 그 외에는 InputStream/Outpurstream 메서드와 같다
문자기반 스트림이라는건 단순히 2 byte로 스트림을 처리하는 것만이 아니다
문자데이터를 다루는데 필요한 또 하나의 정보는 인코딩이다
Reader/Writer와 자손들은 여러종류의 인코딩과 자바에서 사용하는 유니코드(UTF-16)간의 변환을 자동적으로 처리해준다
Reader : 특정 인코딩 -> 유니코드로 변환
Writer : 유니코드 -> 특정 인코딩 변환
FileReader FileWriter
파일로부터 텍스트 데이터를 읽고 파일에 쓰는데 사용된다
//FileInputStream을 사용하면 한글을 사용할 경우 깨진다
PipedReader PipedWriter
쓰레드간에 데이터를 주고받을 때 사용한다
다른 스트림과 달리 입/출력 스트림을 하나의 스트림으로 연결해서 데이터를 주고받는다
스트림을 생성 -> 어느 한쪽 쓰레드에서 connect()를 호출 -> 입/출력 스트림연결
-> 입출력을 마친 후 어느 한쪽 스트림만 닫아도 나머지 스트림은 자동으로 닫힌다
**쓰레드 시작 전 PipedReader PipedWriter를 연결해야 한다**
StringReader와 StringWriter
입출력 대상이 메모리인 스트림이다
StringWriter에 출력되는 데이터는 내부의 StringBuffer에 저장된다
StringBuffer getBuffer() : StringWriter에 출력한 데이터가 저장된 StringBuffer를 반환
String toString() : StringWriter에 출력된 (StringBuffer에 저장된) 문자열을 반환한다
*근본적으로 String도 char배열 하지만 String으로 처리하는 것이 편리한 편이다
문자기반의 보조스트림
BufferedReader BufferedWriter
입출력의 효율을 높일 수 있도록해주는 역할을 한다
->버퍼를 이용하면 입출력의 효율이 비교할 수 없을정도로 좋아진다
BufferedReader : ReadLine()을 사용하면 데이터를 라인단위로 읽는다
->indexOf()를 이용해서 ‘;’를 포함하고 있는지 확인하기도 한다
BufferedWriter : newLine()이라는 줄바꿈 메서드를 가지고 있다
InputStreamReader OutputStreamReader
바이트기반 스트림을 문자기반 스트림으로 연결시켜주는 역할을 한다
바이트기반 스트림의 데이터를 지정된 인코딩의 문자데이터로 변환하는 작업을 수행한다
InputStreamReader 생성자와 메서드
생성자/메서드 | 설명 |
InputStreamReader(InputStream in) | OS에서 사용하는 기본 인코딩의 문자로 변환하는 InputStreamReader를 생성한다 |
InputStreamReader(InputStream in, String encoding) | 지정된 인코딩을 사용하는 InputStreamReader를 생성한다 |
String getEncoding() | InputStreamReader의 인코딩을 알려 준다. |
OutputStreamReader 생성자와 메서드
생성자/메서드 | 설명 |
OutputStreamWriter(OutputStream out) | OS에서 사용하는 기본 인코딩의 문자로 변환하는 OutputStreamWriter를 생성한다 |
OutputStreamWriter(OutputStream out, String encoding) | 지정된 인코딩을 사용하는 OutputStreamWriter를 생성한다 |
String getEncoding() | OutputStreamWriter의 인코딩을 알려 준다. |
->InputStreamReader(InputStream in, String encoding)에서 인코딩을 지정하지 않는다면 OS에서 사용하는 인코딩을 사용해서 파일을 해석해 보여주기 때문에 원래 작성된대로 볼 수 없다
OutputStreamWriter(OutputStream out, String encoding)를 이용해서 인코딩을 지정하지 않으면 OS에서 사용하는 인코딩으로 데이터를 저장할 것이다
**시스템 속성에서 sun.jun.encoding의 값을 보면 인코딩의 종류를 알 수 있다
표준입출력 System.in, System.out, System.err
콘솔(console, 도스창)을 통한 데이터 입력과 콘솔로의 데이터 출력을 의미한다
3가지 입출력 스트림을 제공하는데 이들은 자바의 실행과 동시에 자동적으로 생성되기 때문에 별도의 코드없이 사용가능하다
System.in : 콘솔로부터 데이터를 입력받는데 사용 System.out : 콘솔로부터 데이터를 출력하는데 사용 System.err : 콘솔로부터 데이터를 출력하는데 사용 |
-> in, out, err은 System 클래스에 선언된 클래스 변수이다
ㄴ이들의 타입은 실제로 버퍼를 이용하는 BufferedInputStream과 BufferenOutputStrem의 인스턴스를 사용한다
윈도우에서는 ‘^z’ 유닉스와 매킨토시에서는 ‘^d’를 누르는 것이 스트림의 끝을 의미한다
윈도우의 콘솔을 최대 255자까지만 입력이 가능하다
**^Z-> ctrl+Z를 의미한다**
enter키를 누르는 경우 두 개의 특수문자 \r과 \n이 입력된 것으로 간주된다
\r : 캐리지리턴(carriage return) 커서를 현재 라인의 첫 번째 칼럼으로 이동시킨다
\n : 줄바꿈을 한다
표준입출력의 대상변경
setIn(), setOut(), setErr()를 사용하면 입출력을 콘솔 이외에 다른 입출력 대상으로 변경하는 것이 가능하다
메서드 | 설명 |
static void setOut(PrintStream out) | System.out의 출력을 지정된 PrintStream으로 변경 |
static void setErr(PrintStream err) | System.err의 출력을 지정한 PrintStream으로 변경 |
static void setIn(InputStream in) | System.in의 입력을 지정한 InputStream으로 변경 |
-> JDK1.5부터 Scanner클래스가 제공되면서 System.in으로부터 데이터를 입력받아 작업하는 것이 더 편리해졌다
**System.out, System.err 모두 출력대상이 콘솔이기 때문에 같은 결과를 얻는다
setOut()과 같은 메서드를 사용하는 방법 외에도 커맨드라인에서 표준입출력의 대상을 간단히 바꿀 수 있는 방법이 있다
C:\jdk1.8\work\ch15>java StandardIoex2
out : Hello World!
err : Hello World!
RandomAccessFile
자바는 입력과 출력이 각각 분리되어 별도로 작업을 하도록 설계되어있다
-> RandomAccessFile만은 하나의 클래스로 파일에 대한 입력과 출력을 모두 할 수 있다
In/OutputStream의 상속없이 DataInput 인터페이스와 DataOutput 인터페이스를 모두 구현했기 때문에 읽기와 쓰기가 모두 가능하다
->기본자료형 단위로 데이터를 읽고 쓸 수 있다
가장 큰 장점 : 파일의 어느 위치에나 읽기/쓰기가 가능하다는 것이다 //위치제한이 없다
이것을 가능하게 하기 위해 내부적으로 파일 포인터를 사용한다
현재 작업중인 파일 포인터의 위치를 알고싶을 때는 getFilePointer()를 사용한다
파일 포인터의 위치를 옮길때는 seek(long pos)나 skipBytes(int n)을 사용한다
**모든 입출력은 포인터를 갖고있지만 내부적으로만 사용이 가능하여 위치를 마음대로 변경할 수 없다**