자바의 바이트 스트림(Byte Stream)은 데이터를 8비트 단위의 바이트로 처리하는 입출력 방식입니다. 텍스트뿐만 아니라 이미지, 오디오, 비디오 등 모든 종류의 데이터를 다룰 수 있어 자바 I/O의 기본이 되는 핵심 개념입니다.
바이트 스트림의 최상위 클래스: InputStream과 OutputStream
바이트 스트림 클래스들은 모두 두 개의 추상 클래스를 기반으로 구성됩니다.
- InputStream: 바이트 단위로 데이터를 읽는(입력) 모든 스트림 클래스의 최상위 부모 클래스
- OutputStream: 바이트 단위로 데이터를 쓰는(출력) 모든 스트림 클래스의 최상위 부모 클래스
자바에서 제공하는 대표적인 바이트 스트림 클래스는 다음과 같습니다.
| 입력 스트림 (InputStream) | 출력 스트림 (OutputStream) |
|---|---|
| FileInputStream | FileOutputStream |
| ByteArrayInputStream | ByteArrayOutputStream |
| ObjectInputStream | ObjectOutputStream |
| PipedInputStream | PipedOutputStream |
| FilteredInputStream | FilteredOutputStream |
| BufferedInputStream | BufferedOutputStream |
| DataInputStream | DataOutputStream |
주요 클래스별 역할
- FileInputStream / FileOutputStream: 파일에서 데이터를 읽고 쓸 때 사용합니다.
- ByteArrayInputStream / ByteArrayOutputStream: 메모리 내부의 바이트 배열을 대상으로 입출력을 수행합니다.
- ObjectInputStream / ObjectOutputStream: 객체를 직렬화하여 읽고 쓸 때 사용합니다.
- BufferedInputStream / BufferedOutputStream: 내부 버퍼를 활용해 입출력 성능을 향상시킵니다.
- DataInputStream / DataOutputStream: 자바 기본형(int, double 등) 데이터를 그대로 읽고 쓸 수 있습니다.
실습 예제: FileInputStream으로 파일 읽고 FileOutputStream으로 복사하기
다음 자바 프로그램은 FileInputStream을 사용해 특정 파일에서 데이터를 읽어 들인 후, FileOutputStream을 이용해 다른 파일에 그대로 복사하는 예제입니다.
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class IOStreamsExample {
public static void main(String args[]) throws IOException {
// FileInputStream 객체 생성
File file = new File("D:/myFile.txt");
FileInputStream fis = new FileInputStream(file);
byte bytes[] = new byte[(int) file.length()];
// 파일에서 데이터 읽기
fis.read(bytes);
// 출력 파일 객체 생성
File out = new File("D:/CopyOfmyFile.txt");
FileOutputStream outputStream = new FileOutputStream(out);
// 다른 파일에 데이터 쓰기
outputStream.write(bytes);
outputStream.flush();
System.out.println("데이터가 지정한 파일에 성공적으로 저장되었습니다.");
}
}실행 결과
데이터가 지정한 파일에 성공적으로 저장되었습니다.
정리
바이트 스트림은 8비트 단위로 데이터를 처리하므로 문자, 이미지, 동영상 등 어떤 형식의 파일이든 손실 없이 다룰 수 있습니다. 위 예제처럼 read()와 write() 메서드만으로도 간단하게 파일을 복사할 수 있으며, 실무에서는 성능 향상을 위해 BufferedInputStream/BufferedOutputStream을 함께 사용하는 것이 일반적입니다. 또한 try-with-resources 문법을 활용하면 스트림을 자동으로 닫아 리소스 누수를 방지할 수 있습니다.