Java Input/Ouput Stream #2 (Byte)
바이트 스트림은 바이너리 파일을 입출력 할 때 사용해야 하는 입출력 스트림입니다.
텍스트 파일은 바이너리 파일 중 한가지로 분류해야 옳지만 보통 파일을 비교 할 때는 바이너리 파일과 텍스트 파일로 분류하는 것이 일반적입니다.
바이너리 파일을 아주 간단하게 확인 하는 방법은 메모장에서 파일을 열어보는 것이 가장 쉬운 방법입니다.
텍스트 파일로 오해하기 쉬운 한글문서(확장자명 hwp)를 메모장과 울트라에디트 두 프로그램으로 열어 봤을 때 코드를 확인해 보도록 합시다.
![1.jpg](https://hooni.net/xe/files/attach/images/207/246/002/3aa30973bbc465885a99a2c26e393ec0.jpg)
메모장으로 열였을 때는 텍스트 파일이 아니므로 기계어 코드와 일치하는 문자 코드를 출력하게 되기 때문에 특수문자, 알파벳 등 알수 없는 문자들로 가득차게 됩니다.
![2.jpg](https://hooni.net/xe/files/attach/images/207/246/002/965dd59a431750a9aec15056f2ec56b4.jpg)
울트라에디트의 경우 바이너리 파일을 편집할 때 주로 사용하는 편집기라서 기계어 코드가 출력되게 됩니다.
기계어를 단순히 16진수로 변환해서 보여주는 것이기 때문에 보이는 16진 숫자들은 전부 파일을 이루고 있는 기계어 코드입니다.
보통 울트라에디트를 이용해서 게임 세이브 데이터를 수정할 때 주로 사용하는 경우가 많은데 아주 기초적인 파일 해킹이라고도 하지요.
위와 같이 바이너리 파일은 문자 스트림으로 이용할 수 없게 돼 있습니다.
더 정확하게 말하자면 바이너리 파일을 문자 스트림으로 입출력 한다면 파일이 엉망이 돼서 정상적인 파일로써 가치는 없습니다.
그래서 자바에서는 바이트스트림을 이용해서 바이너리 파일을 입출력 해야 하는 것 입니다.
바이트 스트림 계층도를 보도록 합시다.
![stream02.jpg](https://hooni.net/xe/files/attach/images/207/246/002/dbef00cd6239c8d9585b50590332827c.jpg)
모든 바이트스트림은 InputStream과 OutputStream을 이용해서 자손 클래스들이 구현하고 있습니다.
문자 스트림의 경우와 마찬가지로 InputStream과 OutputStream은 추상클래스입니다.
바이트 스트림 역시 문자 스트림과는 사용법이 크게 다르지 않기 때문에 예문을 보도록 합시다.
import java.io.*; class A { public static void main(String args[]) { String str = null; try { BufferedInputStream bis = new BufferedInputStream( new FileInputStream("A.java")); BufferedOutputStream bos = new BufferedOutputStream( new FileOutputStream("A.txt")); byte buf[] = new byte[256]; int len = 0; while ((len = bis.read(buf, 0, buf.length)) != -1) { str = new String(buf, 0, len); bos.write(buf, 0, len); System.out.println(str); } bis.close(); bos.flush(); bos.close(); } catch (Exception e) {} } }
문자 스트림과 다른 것이 있다면 바이트 스트림은 byte형 변수와 int형 변수를 이용해야 하는 것 입니다.
이 두 변수는 물통과 물통에 표시된 눈금에 해당한다고 할 수 있습니다.
1.5리터 물통 A에서 1.5리터 물통 B로 물을 옮겨 담는다고 했을 때 1리터 짜리 물통(byte)를 이용해서 옮겨 담는다고 하면 두번에 걸쳐 옮겨 담을 수 있습니다.
첫번째 물통으로 물을 옮기면 눈금(int)은 1000cc 일 것입니다.
두번 째는 500cc 일 것입니다.
그러고 난 뒤에는 더이상 물을 옮길 필요가 없기 때문에 끝을 알려줘야 합니다.
그것을 -1 이라고 합시다.
그럼 -1을 담을 수 있는 것은 물통의 눈금입니다.
이로써 물을 다 옮겼다는 표시를 할 수가 있습니다.
이제 이 예를 실제 코드와 맞춰 봅시다.
read 메소드는 버퍼(buf)로 부터 0 부터 버퍼의 길이 만큼(buf.length) 읽어서 그 결과를 int형으로 반환을 해 줍니다.
얼마만큼 읽었는지 알려주는 것이죠.
그것을 len에 저장하고 -1인지 아닌지를 비교 합니다. 더이상 읽어올 것이 없을 경우에 read메소드로 부터 -1이 반환되기 때문에 -1과 비교를 해야 하는 것 입니다.
그럼 저장 할 때는 다르게 해야 합니다.
얼마만큼 넣어야 하는지를 알아야 하기 때문에 buf 배열에서 0 부터 len 길이만큼만 저장을 해야 하는 것 입니다.
만약 이해가 잘 안된다면 "System.out.println(len);" 이 라인을 반복문에 넣어보시면 됩니다.
그럼 반복문이 몇번 실행 되고 얼만큼씩 읽어서 저장하는지를 확인 할 수 있습니다.
이 외에는 문자 스트림과 사용법도 거의 동일하고 크게 다뤄야 할 부분도 없는 것 같습니다.
감사합니다.
No. | Category | Subject | Author | Date | Views |
---|---|---|---|---|---|
265 | Develop |
[ajax] 이벤트 코드 생성기 작업중.. ㅋㅋ
![]() |
hooni | 2013.04.23 | 7177 |
264 | Develop | [php] 날짜 정보 출력 (년,월,일,시,분,초) | hooni | 2013.04.23 | 10586 |
263 | Develop |
[c] KNN(K-nearest neighbor) 패턴인식 과제..
![]() |
hooni | 2013.04.23 | 7417 |
262 | Develop |
[c] 베이지언(Bayesian) 패턴인식 과제 ㅋㅋ
![]() |
hooni | 2013.04.23 | 7121 |
261 | Develop | [js] php의 number_format() 함수와 같은.. ㅋㅋ | hooni | 2013.04.23 | 6957 |
260 | Develop |
[c] 숫자 맞추는 게임..
![]() |
hooni | 2013.04.23 | 6954 |
259 | Develop |
[c] 구조체 배열 예제 (학생 성적 계산)
![]() |
hooni | 2013.04.23 | 7693 |
258 | Develop |
[c] 프로그램 코드(c/c++)를 html 파일로 변환
![]() |
hooni | 2013.04.23 | 7698 |
257 | Develop |
[c] 전위 표기법으로 연산 예제..
![]() |
hooni | 2013.04.23 | 9326 |
256 | Develop | [ajax] 샘플 코드와 한글처리에 대한 간단한 설명 | hooni | 2013.04.23 | 6878 |
255 | Develop | [js] 폼(form) 전송시 중복 클릭 방지 간단한 구문 | hooni | 2013.04.23 | 9330 |
254 | Develop | [js] 사진첩에 쓸 내용 - 마우스 오버로 바꾸기 | hooni | 2013.04.23 | 6365 |