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 |
---|---|---|---|---|---|
589 | Develop | [php] GregorianToJD(), JDToGregorian() 함수 내용 | hooni | 2013.12.25 | 10643 |
588 | Develop | [php] 날짜 정보 출력 (년,월,일,시,분,초) | hooni | 2013.04.23 | 10584 |
587 | Develop |
최근 논문 자료 (2011/01/03, 만현형한테 보낸거..)
![]() |
hooni | 2013.04.23 | 10366 |
586 | Develop | [c] OpenGL 임시로 여기 올림.. | hooni | 2003.04.23 | 10349 |
585 | Develop |
[c++] Window API(MFC) 오목 게임
![]() |
hooni | 2003.04.23 | 10322 |
» | Develop |
[java] 입출력 스트림 2부 (바이트)
![]() |
hooni | 2013.04.23 | 10315 |
583 | Develop |
[php] Laravel 5.4: Specified key was too long error
![]() |
hooni | 2017.12.04 | 10300 |
582 | Develop | [c] pcap을 이용한 패킷 분석 ㅎㅎ | hooni | 2003.04.23 | 10253 |
581 | Develop |
[c] 그래픽스 자료(OpenGL 라이브러리) 샘플 소스
![]() |
hooni | 2003.04.23 | 10217 |
580 | Develop |
[c] 최단거리 알고리즘 & 예제소스..
13 ![]() |
hooni | 2013.04.23 | 10211 |
579 | Develop |
[c] 간단한 자료구조(stack, queue, linked list) 구현 소스
6 ![]() |
hooni | 2003.04.23 | 10170 |
578 | Develop | [c++] p.47 연습문제 3번 | hooni | 2003.04.23 | 10150 |