1. Stream 이란
프로그램은 외부에서 데이터를 읽거나 외부로 데이터를 출력하는 작업이 빈번하게 일어납니다. 이때 데이터는 어떠한 통로를 통해서 데이터가 이동되는데, 이 통로를 Stream 이라고 합니다.
자바에는 이러한 기능을 수행하기 위해 InputStream와 OutputStream이 존재하며 단일 방향으로 연속적으로 흘러갑니다.
InputStream과 OutputStream은 추상 클래스이며 추상 메소드를 오버라이딩해서 다양한 역할을 수행할 수 있습니다.
(예 : 파일, 네트워크, 메모리 입출력)
자바에서 기본적으로 제공하는 I/O 기능은 java.io 패키지에서 제공됩니다.
InputStream은 외부에서 데이터를 읽는 역할을 수행하고, OutputStream은 외부로 데이터를 출력하는 역할을 수행합니다.
2. InputStream
바이트 기반 입력 스트림의 최상위 추상클래스입니다. (모든 바이트 기반 입력 스트림은 이 클래스를 상속받습니다.)
파일 데이터를 읽거나 네트워크 소켓을 통해 데이터를 읽거나 키보드에서 입력한 데이터를 읽을 때 사용합니다.
InputStream은 읽기에 대한 다양한 추상 메소드를 정의해 두었습니다.
그리고 InputStream의 추상메소드를 오버라이딩하여 목적에 따라 데이터를 입력 받을 수 있습니다.
3. InputStream의 기본 메소드
public abstract int read() throws IOException;
public void read() throws IOException {
byte[] bytes = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};
InputStream is = new ByteArrayInputStream(bytes);
int data;
while ((data = is.read()) != -1) {
System.out.print(data);
}
}
입력 스트림에서 1 바이트 씩 읽고 읽은 바이트를 반환합니다.
데이터를 모두 읽었다면 -1을 반환합니다.
출력
------------
1234567891011
public int read(byte buffer[]) throws IOException {
return read(buffer, 0, buffer.length);
}
public void read() throws IOException {
byte[] bytes = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};
InputStream is = new ByteArrayInputStream(bytes);
int len = 3;
int readCnt = 0;
byte[] buffer = new byte[len];
while ((readCnt = is.read(buffer)) != -1) {
for (int index = 0; index < readCnt; index++) {
System.out.print(buffer[index]);
}
System.out.println();
}
}
입력 스트림에서 byte buffer[] 만큼 읽고 읽은 데이터 수를 반환합니다.
여러 바이트 씩 읽기 때문에 한 바이트 씩 읽는 것 보다 더 빠릅니다.
데이터를 모두 읽었다면 -1을 반환합니다.
위 소스는 bytes에 있는 데이터를 buffer의 크기(3)만큼 읽어서 buffer에 넣고 콘솔에 출력하고 read(buffer)의 반환값이 -1이 될 때까지 반복합니다.
read() 메소드와 다른 점은 read() 메소드의 반환 값이 읽은 데이터가 아니라 읽은 데이터 수 라는 점입니다.
읽은 데이터는 매개변수로 넘긴 buffer에 저장됩니다.
출력
------------
123
456
789
1011
public int read(byte buffer[], int off, int len) throws IOException
public void read() throws IOException {
byte[] bytes = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};
InputStream is = new ByteArrayInputStream(bytes);
int len = 4;
int readCnt = 0;
int offset = 0;
byte[] buffer = new byte[1024];
while ((readCnt = is.read(buffer, offset, len)) != -1) {
offset += readCnt;
for (int index = 0; index < offset; index++) {
System.out.print(buffer[index]);
}
System.out.println();
}
}
입력 스트림에서 buffer[off] 부터 len개 만큼 buffer에 저장합니다.
read 메소드는 읽은 데이터의 개수를 반환하고 더 이상 읽을 데이터가 없다면 -1을 반환합니다.
만약 len개를 읽지 못하면 실제로 읽은 데이터 수를 반환합니다.
위 소스는 데이터를 4개씩 읽으며, 다시 읽을 때 배열의 처음 위치가 아닌 offset 위치 즉, buffer[offset] 부터 읽습니다.
offset은 읽은 데이터 수(readCnt) 만큼 증가합니다. 간혹 len만큼 증가하게 하는 경우가 있는데, 읽을 데이터의 수가 꼭 len 값으로 나누어 떨어지지 않기 때문에 offset은 읽은 데이터의 수(readCnt)만큼 증가 해주어야합니다.
보통 네트워크 통신할 때 많이 사용합니다.
출력
------------
1234
12345678
1234567891011
3. OutputStream
바이트 기반 출력 스트림의 최상위 추상클래스입니다.
모든 바이트 기반 출력 스트림 클래스는 이 클래스를 상속 받아 기능을 재정의 합니다.
4. OutputStream의 기본 메소드
public abstract void write(int b) throws IOException;
public void write(byte b[]) throws IOException {
write(b, 0, b.length);
}
public void write01() throws IOException {
byte[] bytes = {9, 8, 7, 6, 5, 4, 3, 2, 1, 0};
File file = new File("D://write_test.txt");
OutputStream outputStream = new FileOutputStream(file);
for (byte b : bytes) {
outputStream.write(b);
}
//바이트를 한번에 넣을 수 있다.
//outputStream.write(bytes);
outputStream.close();
}
바이트 배열을 write_text.txt 파일에 write하는 예제입니다. OutputStream을 상속받은 FileOutputStream을 생성하고, 한 바이트 씩 write하거나 여러 바이트씩 write 할 수 있습니다.
public void write(byte b[], int off, int len) throws IOException
public void write() throws IOException {
byte[] bytes = {9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 7, 8, 7, 8, 5, 2, 4};
int len = 3;
int offset = 0;
int total = bytes.length;
File file = new File("D://write_test.txt");
OutputStream outputStream = new FileOutputStream(file);
while (total >= (offset + len)) {
outputStream.write(bytes, offset, len);
offset += len;
}
if (total - offset > 0) {
outputStream.write(bytes, offset, total - offset);
}
outputStream.close();
}
byte 배열 b를 offset부터 len만큼 write합니다.
public void read() throws IOException {
File file = new File("D://write_test.txt");
InputStream inputStream = new FileInputStream(file);
int b;
while ((b = inputStream.read()) != -1) {
System.out.print(b);
}
}
write_test.txt로 write한 데이터를 한 바이트씩 꺼내서 출력합니다.
public void flush() throws IOException {}
버퍼를 지원하는 경우 버퍼에 존재하는 데이터를 목적지까지 보냅니다.
public void close() throws IOException {
}
OutputStream을 종료합니다.
'JAVA > Chapter14' 카테고리의 다른 글
OutputStream 정의 (0) | 2022.08.25 |
---|---|
InputStream 정의 (0) | 2022.08.25 |
Ch14-50_스트림의 그룹화와 분할 (0) | 2022.01.15 |
Ch14-45_collect()와 Collectors (0) | 2022.01.15 |
Ch14-40_스트림의 최조연산 - forEach() (0) | 2022.01.15 |