게으른 개발자의 끄적거림

Java inputstream outputstream이란?

끄적잉 2024. 8. 6. 21:48

## Java InputStream과 OutputStream에 대한 상세 설명

### 개요
Java의 InputStream과 OutputStream 클래스는 자바 I/O (입출력) 시스템의 핵심 구성 요소로, 파일, 네트워크 연결, 키보드 입력 등 다양한 소스로부터 데이터를 읽고 쓰는 작업을 지원합니다. 이 클래스들은 자바의 java.io 패키지에 속하며, Java에서 데이터 스트림을 다루는 기본적인 방법을 제공합니다. 이 글에서는 InputStream과 OutputStream의 개념, 사용법, 주요 하위 클래스, 그리고 예제 코드에 대해 자세히 설명하겠습니다.


### InputStream

#### 개념
InputStream은 바이트 기반 입력 스트림의 최상위 추상 클래스입니다. 다양한 입력 소스(파일, 네트워크, 메모리 등)로부터 바이트 단위의 데이터를 읽어들이는 데 사용됩니다. InputStream의 주요 메서드들은 데이터를 읽고 스트림을 관리하는 기능을 제공합니다.

#### 주요 메서드
1. `int read()`: 스트림에서 다음 바이트를 읽습니다. 읽을 바이트가 없으면 -1을 반환합니다.
2. `int read(byte[] b)`: 지정된 바이트 배열의 길이만큼 스트림에서 데이터를 읽고 배열에 저장합니다.
3. `int read(byte[] b, int off, int len)`: 스트림에서 최대 len 바이트를 읽고, 이를 지정된 배열의 오프셋 위치에 저장합니다.
4. `void close()`: 스트림을 닫아 더 이상 사용하지 않도록 합니다.

#### 주요 하위 클래스
- **FileInputStream**: 파일로부터 데이터를 읽습니다.
- **ByteArrayInputStream**: 바이트 배열로부터 데이터를 읽습니다.
- **BufferedInputStream**: 데이터를 버퍼링하여 읽기 성능을 향상시킵니다.
- **DataInputStream**: 기본 데이터 타입(int, float 등)을 읽을 수 있습니다.
- **ObjectInputStream**: 객체를 직렬화하여 읽습니다.


### OutputStream

#### 개념
OutputStream은 바이트 기반 출력 스트림의 최상위 추상 클래스입니다. 다양한 출력 소스(파일, 네트워크, 메모리 등)로 바이트 단위의 데이터를 쓰는 데 사용됩니다. OutputStream의 주요 메서드들은 데이터를 쓰고 스트림을 관리하는 기능을 제공합니다.

#### 주요 메서드
1. `void write(int b)`: 스트림에 하나의 바이트를 씁니다.
2. `void write(byte[] b)`: 지정된 바이트 배열의 데이터를 스트림에 씁니다.
3. `void write(byte[] b, int off, int len)`: 지정된 배열의 일부분(len 바이트)을 스트림에 씁니다.
4. `void flush()`: 스트림에 남아 있는 모든 데이터를 실제 출력 장치에 씁니다.
5. `void close()`: 스트림을 닫아 더 이상 사용하지 않도록 합니다.

#### 주요 하위 클래스
- **FileOutputStream**: 파일에 데이터를 씁니다.
- **ByteArrayOutputStream**: 바이트 배열에 데이터를 씁니다.
- **BufferedOutputStream**: 데이터를 버퍼링하여 쓰기 성능을 향상시킵니다.
- **DataOutputStream**: 기본 데이터 타입(int, float 등)을 쓸 수 있습니다.
- **ObjectOutputStream**: 객체를 직렬화하여 씁니다.


### InputStream과 OutputStream의 사용 예제

#### FileInputStream과 FileOutputStream 사용 예제
다음 예제는 파일로부터 데이터를 읽고 다른 파일에 쓰는 간단한 프로그램입니다.

```java
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class FileCopyExample {
    public static void main(String[] args) {
        try (FileInputStream fis = new FileInputStream("input.txt");
             FileOutputStream fos = new FileOutputStream("output.txt")) {
            
            int byteData;
            while ((byteData = fis.read()) != -1) {
                fos.write(byteData);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
```

이 예제는 "input.txt" 파일에서 데이터를 읽어 "output.txt" 파일에 복사합니다. `try-with-resources` 구문을 사용하여 스트림을 자동으로 닫도록 했습니다.

 


#### BufferedInputStream과 BufferedOutputStream 사용 예제
Buffered 스트림을 사용하면 I/O 성능을 크게 향상시킬 수 있습니다. 다음 예제는 BufferedInputStream과 BufferedOutputStream을 사용하는 방법을 보여줍니다.

```java
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class BufferedFileCopyExample {
    public static void main(String[] args) {
        try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream("input.txt"));
             BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("output.txt"))) {
            
            byte[] buffer = new byte[1024];
            int bytesRead;
            while ((bytesRead = bis.read(buffer)) != -1) {
                bos.write(buffer, 0, bytesRead);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
```

이 예제는 1KB 크기의 버퍼를 사용하여 데이터를 읽고 씁니다. Buffered 스트림을 사용하면 파일을 읽고 쓰는 과정에서 성능이 향상됩니다.


#### DataInputStream과 DataOutputStream 사용 예제
Data 스트림은 기본 데이터 타입(int, float, double 등)을 읽고 쓰는 데 사용됩니다.

```java
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class DataStreamExample {
    public static void main(String[] args) {
        try (DataOutputStream dos = new DataOutputStream(new FileOutputStream("data.txt"))) {
            dos.writeInt(123);
            dos.writeDouble(45.67);
            dos.writeBoolean(true);
        } catch (IOException e) {
            e.printStackTrace();
        }

        try (DataInputStream dis = new DataInputStream(new FileInputStream("data.txt"))) {
            int intValue = dis.readInt();
            double doubleValue = dis.readDouble();
            boolean booleanValue = dis.readBoolean();
            
            System.out.println("Int Value: " + intValue);
            System.out.println("Double Value: " + doubleValue);
            System.out.println("Boolean Value: " + booleanValue);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
```

이 예제는 `data.txt` 파일에 정수, 실수, 불리언 값을 쓰고 다시 읽어들입니다. Data 스트림은 자바 기본 데이터 타입을 손쉽게 입출력할 수 있는 편리한 방법을 제공합니다.

 


### 결론
Java의 InputStream과 OutputStream 클래스는 바이트 기반의 I/O 작업을 처리하기 위한 기본적인 도구를 제공합니다. 다양한 입력 및 출력 소스를 지원하며, 이를 통해 파일, 네트워크, 메모리 등에서 데이터를 손쉽게 읽고 쓸 수 있습니다. FileInputStream, FileOutputStream, BufferedInputStream, BufferedOutputStream, DataInputStream, DataOutputStream 등의 하위 클래스를 적절히 활용하면 효율적이고 기능적인 I/O 작업을 수행할 수 있습니다. 위의 예제들을 통해 각 스트림 클래스의 기본적인 사용법과 그 응용 방법을 이해할 수 있었을 것입니다.