▶바이트 단위 스트림
바이트 스트림은 입출력되는 바이트의 바이너리 값을 있는 그대로 처리한다. 그러므로 스트림에 들어오는 데이터가 문자이든 단순 바이너리 정보이든 상관없이 이미지나 오디오까지 읽을 수 있다. 한 바이트씩 읽고 쓴다.
사용자는 InputStream과 OutputStream, 두 메소드를 상황에 맞게 구현하여 사용 가능하다.
InputStream (입력) FileInputStream |
int read() | 해당 입력 스트림으로부터 다음 바이트를 읽어드린다. |
int read(byte[ ] b) | 파라미터로 넣은 배열 크기 만큼 바이트를 읽어들인 후, 배열 b에 저장한다. 그 후 읽은 바이트 수를 반환한다. |
|
int read(byte[ ] b, int off, int size) | size 바이트를 읽어들인 후, 배열에 저장한다. 저장 시작 위치는 b[off]부터이며 읽은 바이트 수를 반환한다. |
|
OutputStream (출력) FileOutputStream |
void write(int b) | 해당 출력 스트림에 특정 바이트를 저장한다 |
void write(byte[ ] b) | 배열 b 길이만큼의 바이트를 해당 출력 스트림에 저장한다 | |
void write(byte[ ] b, int off, int size) | 배열 b의 off 위치부터 size 크기만큼을 출력 스트림에 저장한다. |
● InputStream인 FileInputStream 객체를 생성하여 int read() 형태로 입력 값을 받아오기 예제
package 입출력;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
public class 입출력연습1 {
public static void main(String[] args) {
// TODO Auto-generated method stub
try {
// FileInputStream 에 컨트롤 스페이스 누르ㄱ면 import하는 키 나온다.
// new FileInputStream 에 마우스 올려 놓으면 try - catch 클릭
// ("src/입출력/files/k.txt") 경로를 표시 해 둔 것임
FileInputStream fi = new FileInputStream("src/입출력/files/k.txt");
int ch;
while ((ch = fi.read()) != -1) {
// 읽어드리는 메서드 read() 파라미터가 없지만 read()는 int type 으로 값을 받아온다.
// 따라서 int 타입으로의 반환을 하기 위해서 int ch; 를 만들었음.
System.out.println((char) ch);
// ch 는 int 타입이고 우리는 문자형태로 메세지를 받을 꺼니까 (char)로 형변환.
// fi.read 에 마우스 대고 add catch clause to surrounding try 클릭
}
fi.close();
// 사용이 끝난 객체는 항상 끝을 내줘야 프로그램이 알아듣는다.
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
● InputStream인 FileInputStream 객체를 생성하여 int read(byte [ ] b) 형태로 입력 값을 받아오기 예제
package 입출력;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Arrays;
public class 입출력연습2 {
public static void main(String[] args) {
// TODO Auto-generated method stub
try {
FileInputStream fi = new FileInputStream("src/입출력/files/a.txt");
byte[] buf = new byte[10];
//int read(byte[ ] b) 이 형태로 입력값을 읽어드릴 거라서 byte 배열 생성
int size = 0; //int read 니까 int size 생성
while ((size = fi.read(buf)) > 0) {
System.out.println(new String(buf));
Arrays.fill(buf, (byte) ' ');
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
while ((size = fi.read(buf)) > 0) { System.out.println(new String(buf)); Arrays.fill(buf, (byte) ' '); } |
이 구절이 조금 어려워서 풀어서 이해 해 보려고 한다.
만약에 hello world how are you doing todday라는 문장이 있다고 하면 바이트를 배열에 담아서 입력을 받을 때는 띄어쓰기까지 1바이트로 인식한다. 그렇다면 byte [] buf = new byte [10]; 해당 배열을 이용하여 첫 번째 프린팅을 받아오면 ① hello_worl ② d_how_are_ ③ you_doing_ ④ todayoing_ 이렇게 인식할 것이다. 즉 ④번의 마지막인 today 만을 인식하지 못하고 ③ 번에 덮어 써져 today 5글자를 제외한 oing_ 까지 입력받을 것이다.
이걸 막기 위해 Arrays.fill(buf, (byte) ' ') 이 문장이 사용 된 것이다. Arrays.fill은 자바에서 제공하는 Arrays 유틸리티 클래스의 메서드 중 하나로, 주어진 배열을 특정 값으로 채우는 기능을 한다. buf 이름의 배열을 , ' ' 공백으로 채워줄 건데 buf 배열은 현재 byte 타입의 배열임으로 형변환 (byte)를 해주어 ' ' 공백을 입력해야 한다.
그리고는 new String(buf) byte 타입의 배열을 우리가 읽을 수 있는 문자형 String 으로 변경해 준 후 프린트 해줘야 한다.
그렇다면 while 절 안에 있는 조건은 무엇일까? fi.read(buf) 는 int read(byte[ ] b) 형태로, byte 배열인 이름이 buf를 파라미터로 받아 FileInpuStream의 메서드인 read의 값으로 넣은 것이고 해당 값이 0 보다 작을 때까지 루프를 진행하겠다는 것이다. 이 말은 즉, 바이트로 더 이상 받아 올 값이 없다면 루프를 종료하겠다는 뜻으로 데이터가 없을 때까지 돌겠다는 뜻이다. 이렇게 하면 모든 입력을 다 받아 올 수 있다.
복잡하지만 풀어서 이해하면 이해 할 만하당..!
'JAVA' 카테고리의 다른 글
[JAVA] 입출력 스트림 ③ 문자 단위 스트림 _ 입출력 (0) | 2023.03.11 |
---|---|
[JAVA] 입출력 스트림 ② 바이트 단위 스트림 _ 출력 (0) | 2023.03.11 |
[JAVA] 입출력 스트림 ① 표준 입출력 (0) | 2023.03.08 |
[JAVA] equals()를 재정의 하여 vo 객체 구현 (0) | 2023.03.08 |
[JAVA] equals( ) 메소드 (0) | 2023.03.08 |