본문 바로가기

Java

[Java] 이것이 자바다 - IO 패키지

IO 패키지란?

프로그램에서는 데이터를 외부에서 읽고 다시 외부로 출력하는 작업이 빈번히 일어나는데 자바의 기본적인 데이터 입출력 API는 java.io 패키지에서 제공하고 있다. 이때 프로그램이 출발지냐 또는 도착지냐에 따라서 입출력 스트림의 종류가 결정되는데 프로그램이 데이터를 입력받을 때는 입력 스트림이라고 부르고 프로그램이 데이터를 보낼 때에는 출력 스트림이라고 부른다.

 

java.io 패키지에서 제공하는 스트림의 종류는 크게 두 가지로 구분된다. 하나는 바이트 기반 스트림이고 다른하나는 문자 기반 스트림이다. 바이트 기반 스트림은 그림, 멀티미디어, 문자 등 모든 종류의 데이터를 주고 받을 수 있으나 문자 기반 스트림은 오로지 문자만 주고 받을 수 있다.

 

바이트 기반 스트림과 문자 기반 스트림은 최상위 클래스에 따라서 다음과 같이 구분된다.

 

구분 바이트 기반 스트림 문자 기반 스트림
입력 스트림 출력 스트림 입력 스트림 출력 스트림
최상위 클래스 InputStream OutputStream Reader Writer
하위 클래스 XXXInputStream
(Ex : FileInputStream)
XXXOutputStream
(Ex : FileOutputStream)
XXXReader
(Ex : FileReader)
XXXWriter
(EX : FileWriter)

파일 입출력

파일 생성하고 목록 출력하기

package chap01;

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;

public class FileExample {
	
	public static void main(String[] args) throws Exception {
		// 경로 상에 있는 파일의 객체 생성
		File dir = new File("/파일경로/Dir");
		File file1 = new File("/파일경로/Dir/file1.txt");
		File file2 = new File("/파일경로/Dir/file2.txt");
		File file3 = new File("/파일경로/Dir/file3.txt");
		
		// 경로상의 파일이 존재하지 않을 시 파일 생성
		if (dir.exists() == false) {
			dir.mkdir();
		}
		if (file1.exists() == false) {
			file1.createNewFile();
		}
		if (file2.exists() == false) {
			file2.createNewFile();
		}
		if (file3.exists() == false) {
			file3.createNewFile();
		}
		
		// 아래 File 객체 상에 존재하는 모든 파일 출력
		File temp = new File("/파일경로/Dir");
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd    a    HH:mm");
		File[] contents = temp.listFiles();
		
		System.out.println("날짜            시간            형태            크기            이름");
		System.out.println("--------------------------------------------------------------");
		for (File file : contents) {
			System.out.print(sdf.format(new Date(file.lastModified())));
			if (file.isDirectory()) {
				System.out.print("\t<Dir>\t\t\t" + file.getName());
			} else {
				System.out.print("\t\t\t" + file.length() + "\t" + file.getName());
			}
			System.out.println();
		}
	}
	
}

위 코드를 실행하면 아래와 같이 파일이 생성되고 파일의 정보가 출력된다.

 

FileInputStream

FileInputStream 클래스는 파일로부터 바이트 단위로 읽어들일 때 사용하는 바이트 기반 입력 스트림이다. 바이트 단위로 읽기 때문에 그림, 오디오, 비디오, 텍스트 파일 등 모든 종류의 파일을 읽을 수 있다.

아래는 FileInputStreamExample.java 소스 파일을 읽고 출력하는 예시이다.

public class FileInputStreamExample {

	public static void main(String[] args) {
    
		// 경로 상에 파일이 존재하지 않을때 FileNotFoundException을 발생시키므로 try-catch 문으로 예외 처리 해줌
		try {
			File file = new File(
				"/파일경로/FileInputStreamExample.java"
			);
			FileInputStream fis = new FileInputStream(file);
			int data;
            
			// 1byte씩 읽고 콘솔에 출력
			while ((data = fis.read()) != -1) {
				System.out.write(data);
			}
            
			// 파일의 내용을 모두 읽은 후에는 close() 메소드로 파일을 닫아줌
			fis.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
}

위 코드를 실행 시 아래와 같이 콘솔에 코드가 출력된다.

 

FileOutputStream

FileOutputStream은 바이트 단위로 데이터를 파일에 저장할 때 사용하는 바이트 기반 출력 스트림이다. FileInputStream과 마찬가지로 바이트 단위로 저장하기 때문에 그림, 오디오, 비디오, 텍스트 등 모든 종류의 데이터를 파일로 저장할 수 있다.

아래는 originalFileName String 객체의 경로에 존재하는 파일을 targetFileName 객체의 경로에 복사하는 예시이다.

이미 Dir 폴더에 해당 파일이 존재하는 경우 내용을 덮어 쓰기 때문에 FileOutputStream 을 생성할때 두번째 인자로 true를 주면 뒤에 내용이 추가된다.

public class FileOutputStreamExample {

	public static void main(String[] args) throws Exception {
		String originalFileName = "/파일경로/favicon2.png";
		String targetFileName = "/파일경로/Dir/favicon2.png";
		
		FileInputStream fis = new FileInputStream(originalFileName);
		FileOutputStream fos = new FileOutputStream(targetFileName);
		
		int readByteNo;
		byte[] readBytes = new byte[100];
		
		while ((readByteNo = fis.read(readBytes)) != -1) {
			fos.write(readBytes, 0, readByteNo);
		}
		
		fos.flush();
		fos.close();
		fis.close();
		
		System.out.println("복사가 잘 되었습니다.");
	}
	
}

위 코드를 실행하면 아래와 같이 Dir 폴더에 favicon2.png 파일이 복사된다.

 

FileReader

FileReader 클래스는 FileInputStream과 다르게 텍스트 파일을 프로그램으로 읽어들일 때 사용하는 문자 기반 스트림이다. 문자 단위로 읽기 때문에 텍스트가 아닌 그림, 오디오, 비디오 등의 파일은 읽을 수 없다.

아래는 FileReader를 이용해 FileReaderExample.java 소스 파일을 읽고 출력하는 예시이다.

public class FileReaderExample {

	public static void main(String[] args) {
		try {
			File file = new File(
					"/Users/kimkiyun/Desktop/thisisjava/chap01/src/chap01/FileReaderExample.java"
			);
			FileReader fr = new FileReader(file);
			
			int readCharNo;
			char[] cbuf = new char[100];
			while ((readCharNo = fr.read(cbuf)) != -1) {
				String data = new String(cbuf, 0, readCharNo);
				System.out.print(data);
			}
			fr.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
}

위 코드를 실행 시 아래와 같이 콘솔에 코드가 출력된다.

 

FileWriter

FileWriter는 FileOutputStream과 다르게 텍스트 데이터를 파일에 저장할 때 사용하는 문자 기반 스트림이다. 문자 단위로 저장하기 때문에 텍스트가 아닌 그림, 오디오, 비디오 등의 데이터를 파일로 저장할 수 없다.

아래는 FileWriter를 이용해 문자열 데이터를 맨 처음 생성했던 file1.txt 파일에 저장하는 예시이다.

public class FileWriterExample {

	public static void main(String[] args) throws Exception {
		File file = new File("/Users/kimkiyun/Desktop/Dir/file1.txt");
		FileWriter fw = new FileWriter(file, true);
		fw.write("FileWriter는 한글로된 " + "\r\n");
		fw.write("문자열을 바로 출력할 수 있다." + "\r\n");
		fw.flush();
		fw.close();
		System.out.println("파일에 저장되었습니다.");
	}
	
}

위 코드를 실행 시 아래와 같이 비어있던 file1.txt 파일에 문자열 데이터가 저장된다.