Byte Stream은 데이터를 있는 그대로 송수신 하는 Stream. 그리고 이 Byte Stream을 이용하여 문자를 파일에 저장하는 것도 가능하다. 물론 이렇게 저장된 데이터를 자바 프로그램을 이용해서 읽으면 문제되지 않는다. 하지만 다른 프로그램을 이용해서 읽으면 문제가 될 수 있다.
운영체제 별로 고유의 문자표현방식이 존재한다. 그리고 운영체제에세 동작하는 프로그램은 해당 운영체제의 문자표현 방식을 따른다. 따라서 파일에 저장된 데이터는 해당 운영체제의 문자표현 방식을 따라서 저장되어 있어야 한다.
원 래 Stream은 Byte 단위로 핸들하는 것을 기본으로 한다. 문자도 내부적으로는 Byte 단위로 되어 있으며, 프로그램에서 문자를 사용할 때는 적절한 문자 인코딩으로 변환해서 사용해야 한다. 이러한 불편을 해소하기 위해서 Stream 차원에서 문자를 처리해주는 문자(Character) Stream을 제공하고 있다. Stream을 Byte로 핸들하느냐 문자로 핸들하느냐에 따라서 두 가지 종류로 나눌 수 있다.
스트림의 공통된 특징은 입력 스트림의 경우 read() 계열의 메서드를 사용해서 데이터를 읽어 들이며, 출력 스트림의 경우 write() 계열의 메서드를 사용해서 데이터를 기록한다
Byte Stream
Byte Stream부터 알아보자. Byte Stream은 데이터를 Byte 단위로 주고받는 것을 말한다. 대표적인 Byte Stream은 InputStream과 OutputStream이라고 배웠다. 그렇다면 InputStream과 OutputStream을 통과하는 단위는 당연히 Byte이다. 8bit의 이진 비트를 묶으면 Byte가 되는 바로 그 Byte이다. 원래 데이터는 모두 Byte이다. 알고 보면 그림도 Byte들로 이루어져 있고, 텍스트도 Byte로 이루어져 있다. 그리고 zip이나 jar같은 압축 파일도 일단은 Byte로 되어 있다. 이 Byte들이 적절하게 변환되면 의미 있는 데이터가 되는 것이다. Byte Stream의 경우에는 원시 Byte를 그대로 주고 받겠다는 의미를 담고 있다.
그런데 Character Stream은 이러한 Byte들을 2Byte씩 묶어서 사용할 수도 있고, 1Byte 단위로도 사용할 수 있다. 그것은 문자 인코딩에 따라서 다르게 사용된다. 자바에서 사용하는 문자방식은 유니코드(Unicode) 방식이다. 그래서 Byte로 전송되어지는 것을 Stream에서 재해석한 후 유니코드 문자로 변환하게 된다. 결과적으로 Byte를 Character로 가공을 하는 것이며, 문자의 인코딩은 Character Stream에서 자동으로 해석하게 된다. PPT의 그림은 Stream이 문자를 인코딩하는 것을 보여주고 있다.
Byte Stream은 InputStream과 OutputStream 클래스를 상속하고 있으며, 대부분 InputStream과 OutputStream이라는 단어로 끝난다. 이러한 Byte Stream의 종류는 다음과 같다.
Byte Stream들
- PrintStream
- InputStream, OutputStream
- ByteArrayInputStream, ByteArrayOutputStream
- FileInputStream, FileOutputStream
- FilterInputStream, FilterOutputStream
- ObjectInputStream, ObjectOutputStream
- PipedInputStream, PipedOutputStream
- BufferedInputStream, BufferedOutputStream
- DataInputStream, DataOutputStream
- ... 기타 등등
정말 많다. 그런데 한결같이 InputStream과 OutputStream이라는 단어를 달고 있다. 이러한 Stream을 Byte Stream이라고 한다. 내부적으로 Byte 단위로 Stream 처리를 하는 것이다.
PrintStream에 OutputStream이란 단어가 붙지 않은 이유
PrintStream은 OutputStream밖에 없기 때문에 OutputStream이란 단어를 사용하지 않고 단순히 Print 다음에 Stream을 붙여서 PrintStream이라고 한다.
Character Stream
Character Stream은 Reader와 Writer를 달고 있다. 모두 문자단위로 인코딩 처리를 하는 Stream들이다. Character Stream들은 다음과 같다.
Character Stream들
- PrintWriter
- Reader, Writer
- BufferedReader, BufferedWriter
- CharArrayReader, CharArrayWriter
- FilterReader, FilterWriter
- InputStreamReader, OutputStreamWriter
- FileReader, FileWriter
- PipedReader, PipedWriter
- StringReader, StringWriter
- ... 기타 등등
그 냥 한번 확인해보는 것이지 특별한 의미는 없다. 위의 Stream들은 Character Stream이든 Byte Stream이든, 둘 다 모두 처음엔 Byte로 받아들이는 것은 마찬가지이다. 그리고 해당 Stream이 알아서 처리를 해주는 것이다. 각각의 Stream의 역할은 가공하는 방법과 장치가 다를 뿐 자료의 입출력을 도와주는 중간 매개체로서의 역할은 동일하다. 각 장치에 맞는 Stream을 이용하는 것이 프로그래머가 하는 일이다. 결론적으로 Stream은 원시 데이터를 프로그래머가 사용할 수 있는 데이터로 바꾸어 주는 역할을 한다.
결국 인코딩은 일련의 바이트(8bit)를 유니코드 단위(2 byte 또는 16 bit)단위로 해석하는 과정을 의미한다.
다음의 코드는 바이트단위로 입력받아 문자 스트림으로 처리하는 코드이다. 이때 InputStreamReader로부터 다른 인코딩 방식을 지정할 수도 있으며 이렇게 하므로서 Reader(InputStreamReader)는 한바이트 또는 한바이트 이상을 읽어들여 유니코드로 변환 하는 작업을 알아서 처리해 주게 된다.
public class CharacterStreamTest {
/** * @param args */ public static void main(String[] args) {
try { InputStream in = System.in;
// 입력되는 바이트를 시스템 기본인코딩에의한 문자 스트림으로 변환 한다. // 기스템 기본 인코딩 방식이아닌 다른것을 지정하고 자하는 경우 // InputStreamReader(in, "UTF-8") 등과 같이 인코딩 방식을 지정할 수 있다. InputStreamReader charsIn = new InputStreamReader(in); BufferedReader bufferedCharsIn = new BufferedReader(charsIn);
String line = bufferedCharsIn.readLine(); int i = NumberFormat.getInstance().parse(line).intValue();
System.out.println(i);
} catch (IOException | ParseException e) { System.out.println(e); } }
}
|
'Java > Input/Output Facilities' 카테고리의 다른 글
[NIO] NIO의 기본 개념 (0) | 2013.11.14 |
---|---|
Filter Stream과 Decorator 패턴 (0) | 2013.11.11 |
[바이트 스트림] 데이터 압축 및 해제 - GZIPOutputStream & GZIPInputStream 사용 (0) | 2013.02.11 |
객체의 직렬화 & serialVersionUID (0) | 2013.02.11 |
[객체 스트림] 객체 Write & 객체 Read (0) | 2013.02.11 |