바트심슨으로 하루만 살고 싶다

11. Java ( 입출력과 스트림 ) 본문

Java/Java

11. Java ( 입출력과 스트림 )

바트심슨바게트 2022. 12. 5. 19:04

스트림이란?

자바에서 모든 입출력은 스트림 (stream)을 통해 이루어진다.

입출력 장치는 매우 다양해서 장치에 따라 입출력 부분을 일일이 다르게 구현하면 프로그램 호환성이 떨어질 수밖에 없다.

이러한 문제를 해결하기 위해 자바는 입출력 장치와 무관하고 일관성 있게 프로그램을 구현할 수 있도록 일종의 가상 통로인 스트림을 제공하는 것이다.

스트림을 크게 세 가지 기준에 따라 구분되어진다.

입력 스트림과 출력 스트림

종류
입력 FileInputStream, FileReader, BufferedInputStream, BufferedReader 등
출력 FileOutputStream, FileWriter, BufferedOutputStream, BufferedWriter 등
  • InputStream , Writer 로 끝나면 입력 스트림
  • OutputStream , Reader 로 끝나면 출력 스트림

 

바이트 단위 스트림과 문자 단위 스트림

자바의 스트림은 바이트(byte) 단위로 자료의 입출력이 이루어진다.

하지만 하나의 문자를 나타내는 char형은 2바이트이기 때문에 1바이트만 읽으면 한글 같은 문자는 깨진다.

따라서 읽어 들이는 자료형에 따라 바이트용과 문자용이 따로 나뉘어져 있다.

종류
바이트 스트림 FileOutputStream, FileInputStream, BufferedInputStream, BufferedOutputStream 등
문자 스트림  FileReader, FileWriter, BufferedReader, BufferedWriter 등
  • 스트림 클래스의 이름이 Stream으로 끝나는 경우 바이트 단위를 처리하는 스트림
  • 스트림 클래스의 이름이 Reader 나 Writer 로 끝나는 경우 문자를 위한 스트림 

기반 스트림과 보조 스트림

어떤 스트림이 직접 읽거나 쓰는 기능을 제공하는 스트림인가, 아니면 자료를 직접 읽거나 쓰는 기능은 없이 다른 스트림에

부가 기능을 제공하는가에 따라 나뉜다.

종류
기반 스트림 FileOutputStream, FileInputStream, FileWriter, FileReader 등
보조 스트림 BufferedOutputStream, BufferedInputStream, ,OutputStreamWriter, InputStreamReader
  • 기반 스트림은 직접 입출력 대상에 연결되어 생성되는 스트림 ( File이 붙는게 특징)
  • 보조 스트림은 항상 다른 스트림을 포함하여 생성

 

간략하게 이름을 알아두고, 바이트 단위 스트림과 문자 단위 스트림에 대해서 알아보도록 하자.

바이트 단위 스트림

InputStream

  • 바이트 단위를 읽는 스트림 중 최상위 스트림

주로 사용하는 하위 클래스

  • FileInputStream : 파일에서 바이트 단위로 자료를 읽음
  • ByteArrayInputStream : byte 배열 메모리에서 바이트 단위로 자료를 읽음 
  • FilterInputStream : 기반 스트림에서 자료를 읽을 때 추가 기능을 제공하는 보조 스트림의 상위 클래스

메소드

  • int read( ) : 입력 스트림으로부터 한 바이트의 자료를 읽고, 읽은 자료의 바이트 수를 반환
  • int read( byte [ ] b ) : 입력 스트림으로부터 b[ ] 크기의 자료를 b [ ] 에 읽고 , 읽은 자료의 바이트 수를 반환
  • int read( byte [ ] b, int off, int len ) : 입력 스트림으로부터 b[ ] 크기의 자료를 b [ ] 의 off 변수 위치부터 저장하며 len 만큼 읽고 , 읽은 자료의 바이트 수를 반환
  • void close ( ) : 입력 스트림과 연결된 대상 리소스를 닫는다.

* read ( ) 메소드의 반환형은 int이므로 더이상 읽어 들일 자료가 없는 경우 -1 을 반환

( 파일의 끝에 도달하면 -1 반환 )

 

FileInputStream

  • 파일에서 바이트 단위로 자료를 읽어 들일 때 사용하는 스트림 클래스
  • 사용하기 위해 우선 스트림 클래스 생성

생성자

  • FileInputStream( String name ) : 파일 이름 name(경로 포함) 을 매개변수로 받아 입력 스트림 생성
  • FileInputStream( File f ) : File 클래스의 정보를 매개변수로 받아 입력 스트림 생성

예시

import java.io.FileInputStream;
import java.io.IOException;

public class FileInputStreamTest1 {
	public static void main(String[] args) {

		FileInputStream fis = null;

		try {
			fis = new FileInputStream("input.txt"); // input.txt 파일 입력 스트림 생성
			System.out.println(fis.read());
			System.out.println(fis.read());
			System.out.println(fis.read());

		} catch (IOException e) {
			System.out.println(e);
		} finally {
			try {
				fis.close(); // 열린 스트림은 finally 블록에서 닫음

			} catch (IOException e) {
				System.out.println(e);
			} catch (NullPointerException e) { // 스트림이 null인 경우
				System.out.println(e);
			}
		}
		System.out.println("end");
	}
}

실행 결과

java.io.FileNotFoundException: input.txt (지정된 파일을 찾을 수 없습니다)
java.lang.NullPointerException: Cannot invoke "java.io.FileInputStream.close()" because "fis" is null
end

try - catch문을 통해서 어떤 예외가 발생하고 어떻게 처리해야 하는지 알 수 있다.

만약 어떻게 예외를 처리해야 하는지 모르는 경우 최상위 클래스인 Exception을 사용하면 된다.

 

 

OutputStream

  • 바이트 단위로 쓰는 최상위 스트림

자료의 출력 대상에 따른 스트림을 제공

  • FileOutputStream : 바이트 단위로 파일에 자료를 쓴다.
  • ByteArrayOutputStream : Byte 배열에 바이트 단위로 자료를 쓴다.
  • FilterOutputStream : 기반 스트림에서 자료를 쓸 때 추가 기능을 제공하는 보조 스트림의 상위 클래스

메소드

  • void write(int b) : 한 바이트 출력
  • void write(byte[ ] b) : b[ ] 배열 안에 있는 자료 출력
  • void write(byte[ ] b, int off, int len) : b[ ] 배열 안에 있는 자료의 off 위치부터 len 개수 만큼 자료를 출력
  • void flush( ) : 출력을 위해 잠시 자료가 머무르는 출력 버퍼를 강제로 비워 자료를 출력
  • void close( ) : 출력 스트림과 연결된 대상 리소스를 닫고, 출력 버퍼가 지워진다.

FileOutputStream

생성자

  • FileOutputStream(String name) : 파일 이름 name을 매개변수로 받아 출력 스트림 생성
  • FileOutputStream(String name, boolean append) : 파일 이름 name을 매개변수로 받아 출력 스트림 생성, append 값이 true >> 파일 스트림을 닫고 다시 생성할 때 파일의 끝에 이어서 쓴다. false 는 디폴트 값
  • FileOutputStream(File f) : File 클래스 정보를 매개변수로 받아 출력 스트림 생성
  • FileOutputStream(File f, boolean append) : File 클래스 정보를 매개변수로 받아 출력 스트림 생성, append 값이 true >> 파일 스트림을 닫고 다시 생성할 때 파일의 끝에 이어서 쓴다. false 는 디폴트 값

예시

import java.io.FileOutputStream;
import java.io.IOException;

public class FileOutputStreamTest1{
	public static void main(String[] args) {


		try(FileOutputStream fos = new FileOutputStream("output.txt");) {
			
			fos.write(65);
			fos.write(66);
			fos.write(67);
		} catch (IOException e) {
			e.printStackTrace();
		}
		System.out.println("출력이 완료되었습니다.");
	}
}

output.txt 파일에 저장된 데이터

ABC	//FileOutputStream은 숫자를쓰먄 해당하는 아스키 코드 값으로 변환됨

문자 단위 스트림

Reader

  • 문자 단위로 읽는 스트림 중 최상위 스트림

주로 사용하는 하위 클래스

  • FileReader : 파일에서 문자 단위로 읽는 스트림 클래스 
  • InputStreamReader : 바이트 단위로 읽은 자료를 문자로 변환해주는 스트림 클래스
  • BufferedReader : 분자로 읽을 때 배열을 제공하여 한꺼번에 읽을 수 있는 기능을 제공해주는 보조 스트림

메소드

  • int read( ) : 파일로 부터 한 문자를 읽고, 읽은 값을 반환
  • int read(char [ ] buf) : 파일로부터 buf 배열에 문자를 읽는다.
  • int read(char [ ] buf, int off, int len) : 파일로부터 buf 배열의 off 위치에서부터 len 개수만큼 문자를 읽는다.
  • void close( ) : 스트림과 연결된 파일 리소스를 닫는다.

FileReader

  • FileInpuStream과 마찬가지로 읽으려는 파일이 없으면 예외 발생

생성자

  • FileReader(String name) : 파일 이름 name을 매개변수로 받아 입력 스트림 생성
  • FileReader(File f) : File 클래스 정보를 매개변수로 받아 입력 스트림 생성

"안녕하세요" 를 저장한 reader.txt 파일을 바이트단위로 불러와 보면

import java.io.FileInputStream;

public class FileInputStreamTest {
	public static void main(String[] args) {

		try (FileInputStream fis = new FileInputStream("reader.txt")) {
			int i;
			while ((i = fis.read()) != -1) {
				System.out.println((char) i);
			}
			System.out.println("end");
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}
%
?
¿
?
?
?
%
%
¿
?
end

한글을 바이트 단위로 읽어 오니 글자가 깨져서 나타난다.

이번에는 문자 스트림을 이용해서 다시 읽어와 보자.

import java.io.FileReader;

public class FileReaderTest{
	public static void main(String[] args) {

		try (FileReader fr = new FileReader("reader.txt")) {
			int i;
			while ((i = fr.read()) != -1) {
				System.out.println((char) i);
			}
			System.out.println("end");
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

 

안녕하세요

이처럼 Reader 클래스는 문자를 처리할 때 사용하는 클래스 이다.

 

Writer

  • 문자 단위로 출력하는 스트림 중 최상위 스트림

주로 사용하는 하위 클래스

  • FileWriter : 파일에 문자 단위로 출력하는 스트림 클래스
  • OutputStreamWriter : 파일에 바이트 단위로 출력한 자료를 문자로 변환해 주는 보조스트림
  • BufferedWriter : 문자로 쓸 때 배열을 제공하여 한꺼번에 쓸 수 있는 기능을 제공하는 보조 스트림

메소드

  • void write (int c) : 한 문자를 파일에 출력
  • void write (char[ ] buf) : 문자 배열 buf의 내용을 파일에 출력
  • void write (char[ ] buf, int off, int len) : 문자 배열 buf의 내용을 off위치에서 부터 len 개수만큼 파일에 출력
  • void write(String str) : 문자열 str을 파일에 출력
  • void write(String str, int off, int len) : 문자열 str의 off번째 문자부터 len 개수만큼 파일에 출력
  • void flush( ) : 파일에 출력하기 위해 자료가 있는 공간을 비워 출력한다.
  • void close( ) : 파일과 연결된 스트림을 닫으며 , 출력 버퍼도 비워진다.

FileWriter

  • Writer 스트림 중 가장 많이 쓰이는 스트림 클래스

생성자

  • FileWriter(String name) : 파일 이름 name을 매개변수로 받아 출력 스트림 생성
  • FileWriter(String name, boolean append) : 파일 이름 name을 매개변수로 받아 출력 스트림 생성, append 값이 true >> 파일 스트림을 닫고 다시 생성할 때 파일의 끝에 이어서 쓴다. false 는 디폴트 값
  • FileWriter(File f) : File 클래스 정보를 매개변수로 받아 출력 스트림 생성
  • FileWriter(File f, boolean append) : File 클래스 정보를 매개변수로 받아 출력 스트림 생성, append 값이 true >> 파일 스트림을 닫고 다시 생성할 때 파일의 끝에 이어서 쓴다. false 는 디폴트 값

예시

import java.io.FileWriter;

public class FileWriterTest {
	public static void main(String[] args) {

		try (FileWriter fw = new FileWriter("writer.txt")) {
			fw.write("A");
			char buf[] = { 'B', 'C', 'D', 'E', 'F', 'G' };
			
			fw.write(buf);
			fw.write("안녕하세요. 잘 써지네요.");
			fw.write(buf, 1, 2);
			fw.write("65");
			}
		catch(Exception e) {
			e.printStackTrace();
		}
	System.out.println("출력이 완료되었습니다.");
	}
}

writer.txt 출력

ABCDEFG안녕하세요. 잘 써지네요.CD65

 

'Java > Java' 카테고리의 다른 글

14. Java( 제네릭 )  (0) 2022.12.31
Java (set 인터페이스 - HashSet, TreeSet)  (0) 2022.12.30
Java (try catch 구문)  (1) 2022.11.29
Java(버블정렬 - 올림차순 정렬)  (0) 2022.11.29
10. Java( 전역변수 , 지역변수)  (0) 2022.11.29
Comments