Java

Java 프로그래밍 입출력, IO패키지

Uisin 2024. 9. 25. 16:45

IO와 스트림(Stream)


IO란?

 Input과 Output의 준말로 마우스,키보드 입력 등 프로그램을 들어오는 값을 Input 값, 모니터, 스피커 출력 등 밖으로 나가는 값을 Output값이라 한다

 

Stream이란?

  • 스트림이란 데이터의 연속적인 흐름을 의미하는데 말 그대로 강 줄기가 흘러가듯 한 방향으로 데이터처리가 이뤄진다는 점이 있다.
  • 단방향인 만큼 시작하는 점과 끝나는 점이 있는 이를 Input과 Output으로 나타낼 수 있다.
  • 예를 들어 키보드를 통해 무언가를 입력하고 프로그램을 통해 모니터로 출력이 된다면 이는 곧 키보드에서 모니터까지 한 방향으로 데이터가 흘러간다고 볼 수 있다.
  • 이러한 구조 때문에 입력 스트림과 출력 스트림을 각각 따로 사용해야 하며 먼저 들어온 데이터가 먼저 나가는 First in first out (FIFO) 구조를 이룬다
  • 스트림은 출력 단위가 바이트 단위인 바이트기반 스트림과 출력 단위가 문자 단위인 문자 기반 스트림으로 나눠진다

 

바이트기반 스트림

  • 바이트기반 스트림은 바이트단위로 데이터를 입출력하는 스트림이다
  • 1byte씩 끊어서 읽고 출력한다
  • InputStream, OutputStream 클래스가 모든 바이트기반 스트림들의 조상이 된다
  • InputStream을 상속받는 스트림은 read() 추상 메서드를 구현한다
  • OutputStream을 상속받는 스트림은 write() 추상 메서드를 구현한다

 

InputStream의 메서드

 <int read()>

: 내용을 읽고 그 값을 정수로 반환하는데, 파일의 끝에 (eof) 도달하거나 스트림이 종료되면 -1을 반환한다


 <int read(byte[] b)>

: 파일 내용을 한번에 모두 읽어서 배열에 저장


 <int read(byte[] b, int off, int len)>

 : len 길이만큼 읽어서 배열의 off 번째 위치부터 저장

 

 

OutputStream의 메서드

 <void write(int b)>

 : b의 하위 8비트를 출력 스트림에 적는다


 <void write(byte[] b)>

: 배열 변수 b의 모든 요소들을 출력 스트림에 적는다


 <void write(byte[] b, int off, int len)>

 : off 위치 부터 len 개의 b의 요소를 출력 스트림에 적는다

 

 

FileInputStream/FileOutputStream

  • 추상클래스인 InputStream과 OutputStream의 하위 클래스로 이들로부터 기능을 상속 받아 데이터를 읽어오고 쓰는 등의 처리를 하는 클래스다.
  • 컴퓨터의 파일 시스템과 직접 연결되서 컴퓨터의 저장 장치에 저장된 파일을 다루는데 특화되어 있다
  • 처리하고자 하는 파일이 존재하지 않거나 권한이 없는 경우가 있기에 반드시 try-catch 예외처리를 해야 사용 가능하다
    파일 입출력을 맟니 후에는 반드시 close() 메서드를 이용해 스트림을 닫아줘야 한다 (출력스트림-입력스트림 순)


바이트 기반 보조 스트림

 말 그대로 바이트 기반 스트림의 성능을 향상시키기 위해 보조해주는 역할을 하는 스트림이다. FileInputStream 같은 스트림이 할 수 없는 기능을 이용하고 코드의 가독성을 높여주기 때문에 사용한다. 데이터를 전송할 스트림을 선언하고 그 스트림을 인자로 보조 스트림의 생성자로 넣어주면 된다


InputStream계열

<BufferedInputStream>

: 여러 번 읽기 작업을 할 때, 한 번에 많은 양의 데이터를 미리 읽어 버퍼에 저장해 두었다가 필요할 때마다 버퍼에서 가져오는 방식이라 파일 시스템에 접근해야하는 횟수를 줄여 성능을 향상 시켜줌


<DataInputStream>

 : 바이트 스트림을 기본형 데이터(int, double 등)로 변환하여 읽어옴

 

 

 

OutputStream 계열

BufferedOutputStream  : 여러 번 쓰기 작업을 할 때, 데이터를 버퍼에 모아뒀다가 한번에 출력해 성능을 향상시킴
DataOutputStream : 기본형 데이터를 바이트 스트림으로 변환하여 출력함
PrintStream : print(), println() 등의 메서드를 제공하여 문자열을 편리하게 출력할 수 있도록 함

 

 

 

스트림의 예외 처리

 우리가 주로 사용할 FileInputStream/FileOutputStream의 경우 앞서 설명했듯이 다루고자 하는 파일이 누락되거나 디스크의 공간이 부족하거나 권한이 없는 등, 처리하고자 하는 데이터(파일)에 접근이 불가능한 경우가 생길 수 있다. 그렇기 때문에 Java에서는 FileInputStream/FileOutputStream 외 다른 Stream 들을 포함해서 대부분의 경우에 throws나 try-catch 예외 처리를 강제하고있다.

	public static void main(String[] args) 
	{
		FileInputStream fis = null;
		BufferedInputStream bis = null; 
		FileOutputStream fos = null;
		BufferedOutputStream bos = null;
		//
        //
		try {
			fis = new FileInputStream("C:\\prac.txt");
			bis = new BufferedInputStream(fis);
			fos = new FileOutputStream("result.txt");
			bos = new BufferedOutputStream(fos);

			int data;
			while((data = fis.read()) != -1) 
			{
				bos.write(data);
			}

			bos.close();
			bis.close();
			fos.close();
			fis.close();

		}catch (Exception e) {e.printStackTrace();}

	}

 

 

한 줄 정리

  • IO는 Input과 Output의 준말로 값을 들여보내고 내보내는 것을 의미한다
  • Stream이란 Input과 Output을 통해 데이터를 연속적으로 처리하는 개념으로, FIFO 구조를 가지며 바이트 기반과 문자 기반 스트림이 있다
  • 바이트기반 스트림은 InputStream과 OutputStream으로 나눌 수 있으며 각각 read(), write() 추상 메서드를 포함한다
  • read()는 내용을 읽고 내용이 없으면 -1을 반환한다
  • write(int b)는 b의 하위 8비트를 출력 스트림에 적는다
  • FileInputStream/FileOutputStream은 컴퓨터의 저장 장치에 저장된 파일을 다루는데 특화된 스트림이다
  • 바이트 기반 보조 스트림은 기본 스트림의 성능을 향상시켜주는 역할을 한다
  • 스트림 사용 시에는 반드시 예외 처리를 해주어야 하며, 사용 후 close() 메서드로 스트림을 닫아주어야 한다
  • 스트림 클래스 선언 시 초기화를 null로 해주는 것이 권장된다