ksouth9

입출력 I/O(2) - 바이트기반 스트림 본문

Java

입출력 I/O(2) - 바이트기반 스트림

ksouth9 2022. 4. 17. 21:39

InputStream과 OutputStream


InputStream과 OutputStream은 모든 바이트기반의 스트림의 조상이다.

 

InputStream 메서드

메서드명 설명
int available() 스트림으로부터 읽어 올 수 있는 데이터의 크기를 반환한다.
void close() 스트림을 닫음으로써 사용하고 있던 자원을 반환한다.
void mark(int readlimit) 현재위치를 표시해 놓는다. 후에 reset()에 의해서 표시해 놓은 위치로 다시 돌아갈 수 있다. readlimit은 돌아갈 수 있는 byte의 수이다.
boolean markSupported() mark()와 reset()을 지원하는지를 알려 준다. mark()와 reset()기능을 지원하는 것은 선택적이므로, mark()와 reset()을 사용하기 전에
markSupported()를 호출해서 지원여부를 확인해야한다.
abstract int read() 1 byte를 읽어 온다(0~255사이의 값) 더 이상 읽어 올 데이터가 없으면 -1을 반환한다. abstract메서드라서 InputStream의 자손들은 자신의 상황에 알맞게 구현해야한다.
int read(byte[] b) 배열 b의 크기만큼 읽어서 배열을 채우고 읽어 온 데이터의 수를 반환한다. 반환하는 값은 항상 배열의 크기보다 작거나 같다.
int read(byte[] b, int off, int len) 최대 len개의 byte를 읽어서, 배열 b의 지정된 위치(off)부터 저장한다.
실제로 읽어 올 수 있는 데이터가 len개보다 적을 수 있다.
void reset() 스트림에서의 위치를 마지막으로 mark()이 호출되었던 위치로 되돌린다.
long skip(long n) 스트림에서 주어진 길이(n)만큼을 건너뛴다.

OutputStream 메서드

메서드명 설명
void close() 입력소스를 닫음으로써 사용하고 있던 자원을 반환한다.
void flush() 스트림의 버퍼에 있는 모든 내용을 출력소스에 쓴다.
abstract void write(int b) 주어진 값을 출력소스에 쓴다.
void write(byte[] b) 주어진 배열 b에 저장된 모든 내용을 출력소스에 쓴다.
void write(byte[] b, int off, int len) 주어진 배열 b에 저장된 내용 중에서 off번째부터 len개 만큼만을 읽어서 출력소스에 쓴다.

스트림의 종류에 따라서 mark()와 reset()을 사용하여 이미 읽은 데이터를 되돌려서 다시 읽을 수 있다. 이 기능을 지원하는 스트림인지 확인하는 markSuppoprted()를 통해서 알 수 있다. flush()는 버퍼가 있는 출력스트림의 경우에만 의미가 있으며, OutputStream에 정의된 flush()는 아무런 일도 하지 않는다.

 

프로그램이 종료될 때, 사용하고 닫지 않은 스트림을 JVM이 자동적으로 닫아 주기는 하지만, 스트림을 사용해서 모든 작업을 마치고 난 후 에는 close()를 호출해서 반드시 닫아 주어야 한다. 그러나 ByteArrayInputStream과 같이 메모리를 사용하는 스트림과 System.in, System.out과 같은 표준 입출력 스트림은 닫아 주지 않아도 된다.

ByteArrayInputStream과 ByteArrayOutputStream


ByteArrayInputStream과 ByteArrayOutputStream은 메모리, 즉 바이트배열에 데이터를 입출력 하는데 사용되는 스트림이다. 

주로 다른 곳에 입출력하기 전에 데이터를 임시로 바이트배열에 담아서 변환 등의 작업을 하는데 사용된다. (자주 사용되지는 않는다.)

 

ByteArrayInputStream과 ByteArrayOutputStream을 이용해서 바이트배열 inSrc의 데이터를 ourtSrc로 복사하는 예제

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.util.Arrays;

public class IOEx1 {

	public static void main(String[] args) {
		byte [] inSrc = {0,1,2,3,4,5,6,7,8,9};
		byte [] outSrc = null;
		
		ByteArrayInputStream input = null;
		ByteArrayOutputStream output = null;
		
		input = new ByteArrayInputStream(inSrc);
		output = new ByteArrayOutputStream();
		
		int data = 0;
		
		while ((data = input.read())!=-1) {
			output.write(data);	// void write(int b)
		}
		outSrc = output.toByteArray();	// 스트림의 내용을 byte배열로 반환한다.
		
		System.out.println("Input Source : "+Arrays.toString(inSrc));
		System.out.println("Output Source : "+Arrays.toString(outSrc));
	}

}//실행결과
Input Source : [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
Output Source : [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

read()와 write()를 사용하는 가장 기본적인 방법을 보여준다.

 

while문의 조건식은 아래와 같은 순서로 처리된다.

(data = input.read())!= -1

data = input.read()	// read()를 호출한 반환값을 변수 data에 저장한다.(괄호먼저)
data != -1		// data에 저장된 값이 -1이 아닌지 비교한다.

int read(byte[] b, int off, int len)와 void write(byte[] b, int off, int len)를 사용해서 입출력하는 방법을 보여주는 예제

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.util.Arrays;

public class IOEx2 {

	public static void main(String[] args) {
		byte[] inSrc = {0,1,2,3,4,5,6,7,8,9};
		byte[] outSrc = null;
		byte[] temp = new byte[10];
		
		System.out.println(Arrays.toString(temp));
		
		ByteArrayInputStream input = null;
		ByteArrayOutputStream output = null;

		input = new ByteArrayInputStream(inSrc);
		output = new ByteArrayOutputStream();
		
		input.read(temp,0,temp.length);	// 읽어 온 데이터를 배열 temp에 담는다.
		output.write(temp,5,5);			// temp[5]부터 5개의 데이터를 write한다.
		
		outSrc = output.toByteArray();
		
		System.out.println("Input Source : "+Arrays.toString(inSrc));
		System.out.println("temp : "+Arrays.toString(temp));
		System.out.println("Output Source : "+Arrays.toString(outSrc));
	}

}//실행결과
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
Input Source : [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
temp : [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
Output Source : [5, 6, 7, 8, 9]

FileInputStream과 FileOutputStream


FileInputStream과 FileOutputStream은 파일에 입출력을 하기 위한 스트림이다.

생성자 설명
FileInputStream(String name) 지정된 파일이름(name)을 가진 실제 파일과 연결된 FileInputStream을 생성한다.
FileInputStream(File file) 파일의 이름이 String이 아닌 File인스턴스로 지정해주어야 하는 점을 제외하고 FileInputStream(String name)와 같다.
FileInputStream(FileDescriptor fdObj) 파일 디스크립터(fdObj)로 FileInputStream을 생성한다.
FileOutputStream(String name) 지정된 파일이름(name)을 가진 실제 파일과의 연결된 FileOutputStream을 생성한다.
FileOutputStream(String name, boolean append) 지정된 파일이름(name)을 가진 실제 파일과 연결된 FileOutputStream을 생성한다. 두 번째 인자인 append를 true로 하면, 출력 시 기존의 파일내용의 마지막에 덧붙인다. false면, 기존의 파일내용을 덮어쓰게 된다.
FileOutputStream(File file) 파일의 이름을 String이 아닌 File인스턴스로 지정해주어야 하는 점을 제외하고 FIleOutputStream(String name)과 같다.
FileOutputStream(File file, boolean append) 파일의 이름을 String이 아닌 File 인스턴스로 지정해주어야 하는 점을 제외하고 FileOutputStream(String name, boolean append)과 같다.
FileOutputStream(FileDescriptor fdObj) 파일 디스크립터(fdObj)로 FileOutputStream을 생성한다.

 

'Java' 카테고리의 다른 글

입출력 I/O(3) - 바이트기반 보조스트림(2)  (0) 2022.04.27
입출력 I/O(3) - 바이트기반 보조스트림  (0) 2022.04.21
입출력 I/O(1)  (0) 2022.04.17
람다식(Lambda expression)(2)  (0) 2022.04.16
람다식(Lambda expression)(1)  (0) 2022.04.11