본문 바로가기
Back/JAVA

시스템과 파일 입출력(Java.io) - Input, Output, Stream, Reader, Writer, File

by 시월해 2021. 3. 18.

* java에서의 입출력 방식


 - 스트링이라는 개념을 사용함.
 - 스트림의 사전적 의미 : 시냇물이라는 뜻을 가지고 있음.
                   즉, 데이터가 물 흐르는 것처럼 흐른다고 생각하면 됨.
 - java에서의 스트림 : 순서가 있는 일련의 연속된 데이터


* 스트림의 종류

  1) 바이트 스트림 방식으로 데이터를 입출력하는 클래스.
       ==> xxxInputStram / xxxOutputStream
  2) 문자 스트림 관련 클래스
     - 문자 스트림 방식으로 데이터를 입출력하는 클래스.
       ==> xxxReader / xxxWriter
  3) 바이트 스트림 -> 문자 스트림으로 변환하는 클래스
     ==> InputStreamReader / OutputStreamWriter
 


 - java 입출력 관련 클래스 : java..io 패키지에 존재함.
                  ==> 해당 패키지에 있는 클래스들을 이용하여 파일을 입출력함.
 - checked 방식의 예외 처리가 적용됨.
 - java의 입출력은 단방향성 ==> 한쪽 방향으로만 입력되고 출력이 됨.
 - FIFO(First In First Out) : 먼저 입력되어 먼저 출력이 됨.

 

* File 클래스


 - 파일 및 디렉토리(폴더)를 만들어 주는 클래스.
 - 파일 입출력 시에 사용이 됨.
 - 파일 디렉토리에 대한 경로명, 크기, 타입, 수정 날짜 등의 속성을 제공함.
    또한 파일 삭제, 디렉토리 생성, 파일 이름 변경, 디렉토리 내의 파일 리스트 제공 등 다양한 파일 관리 작업을 지원함.

 

 1. FileInputStream / FileOutputStream
    - 1바이트 단위로 파일을 처리하는 바이트 기반 입출력 스트림
     - 그림(이미지), 오디오 파일 등 모든 종류의 파일 처리가 가능.
 2. FileReader / FileWriter
     - 2바이트 단위로 파일을 처리하는 문자 기반 입출력 스트림
     - 문자 단위로 처리를 하기 때문에 그림, 오디오 파일들은 처리가 불가능.

 




기본예제)

import java.io.IOException;

public class Ex01 {

	public static void main(String[] args) {
		
		System.out.println("한 문자를 입력하세요...");
		
		// system.in : 표준입력장치(키보드)
		// read() : 표준입력장치를 통해서 입력받은 데이터를 읽게 됨. 읽으면 ASCII코드(숫자)로 반환됨.
		try {
			int num = System.in.read();
			System.out.println("읽어온 데이터(ASCII) >>> " + num);
			System.out.println("읽어온 데이터(문자) >>> " + (char)num);
		} catch (IOException e) {
			e.printStackTrace();
		}

	}

}

대문자 A를 입력하면 A의 아스키값이 65가 출력되는 것을 볼 수 있다.

 


예제1)

import java.io.IOException;

public class Ex03 {

	public static void main(String[] args) {
		
		System.out.println("한 줄을 입력하세요.....");

		int readByte;
		
		
		try {
			while(true) {
				readByte = System.in.read();
				if(readByte == '\n') {
					break;
				}
				
				System.out.print((char)readByte);
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}

}

시스템을 통해 1byte단위로 받기 때문에 영어로 입/출력하면 정상적으로 되지만,
한글을 입력하면 문자가 깨진다.


예제2) 한글 입/출력을 받기위해 InputStreamReader 사용

import java.io.IOException;
import java.io.InputStreamReader;

public class Ex04 {

	public static void main(String[] args) {
		
		System.out.println("입력 후 끝이라고 입력하세요...");

		InputStreamReader isr = new InputStreamReader(System.in);
		
		int readByte;
		
		try {
			while(true) {
				readByte = isr.read();
				if(readByte == '끝') {
					break;
				}
				System.out.print((char)readByte);
			} // while end.
			// while문 흐름 : true로 무한 루프를 돌면서 reader로 받은 값을 차례대로 비교 후 출력을 반복하다가 비교한 값이 '끝'이면 break한다.
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			try {
				
				// 입출력 스트림은 닫아주는 것이 좋다.
				isr.close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		
	}

}

한글이 정상적으로 입/출력 되는 것을 볼 수 있다.


예제3) 파일입출력

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;

public class Ex05 {

	public static void main(String[] args) {
		
		InputStream is = null;
		
		int readByte;
		
		try {
			is = new FileInputStream("C:/test/sample.txt");
			
			while(true) {
				readByte = is.read();
				
				// 파일을 읽을 때 더이상 데이터가 없는 경우 -1이라는 값을 반환
				if(readByte == -1) {
					break;
				}
				
				System.out.print((char)readByte);
			}
			is.close();
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

}

Sample.txt 파일에 있는 내용을 프로그램으로 읽어들여 출력해준 것을 볼 수 있다.

 


예제4) 보조 스트림을 사용하지 않은 경우와 사용한 경우의 프로그램 속도 측정

import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

public class Ex08 {

	public static void main(String[] args) {
		
		long start, end;
		
		// 1. 바이트 기반 스트림을 사용한 경우
		try {
			FileInputStream fis = new FileInputStream("C:/test/Koala.jpg");
			
			start = System.currentTimeMillis();
			
			while(fis.read() != -1) { }
			
			end = System.currentTimeMillis();
			
			System.out.println("바이트 스트림을 사용한 경우 >>> "+(end-start)+"ms");
			
			fis.close();
		
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		// 2. 보조스트림을 사용한 경우
		try {
			FileInputStream fis1 = new FileInputStream("C:/test/Koala.jpg");
			BufferedInputStream bis = new BufferedInputStream(fis1);
			
			start = System.currentTimeMillis();
			
			while(fis1.read() != -1) { }
			
			end = System.currentTimeMillis();
			
			System.out.println("보조 스트림을 사용한 경우 >>> "+(end-start)+"ms");
			
			bis.close();
			fis1.close();
		
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

}

보조스트림을 사용했을 때 실행 속도가 조금 더 빠른 것을 볼 수 있다.


예제5) 파일 복사

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

public class Ex09 {

	public static void main(String[] args) {
		
		// 원본 이미지 파일
		try {
			FileInputStream fis = new FileInputStream("C:/hyebin/test/Koala.jpg");
			
			//원본 이미지 파일이 복사되어 저장될 파일
			FileOutputStream fos = new FileOutputStream("C:/hyebin/test/Copied.jpg");
		
			int readByte;
			
			while(true) {
				readByte = fis.read();
				
				if(readByte == -1) {
					break;
				}
				
				// int값이 옆으로 한byte씩 출력이 되어 파일을 완성한다.
				fos.write(readByte);
			} // while end
			
			// 입출력 객체 닫기
			fos.close();
			fis.close();
			
			System.out.println("복사 완료!");
			
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

}

현재는 Copied.jpg 파일이 없다.
실행 완료
Copied.jpg 파일이 생성됨


예제6) 파일 및 디렉토리를 만들어 보자.

import java.io.File;
import java.io.IOException;

public class Ex10 {

	public static void main(String[] args) {
		// C:/sample 폴더를 만들어 보자.
		File dir = new File("C:/sample");
		
		// 해당 디렉토리가 존재하지 않을 때만 생성
		if(!dir.exists()) {
			dir.mkdir(); // 실제로 폴더를 만들어 주는 메서드.
		}
		
		// C:/sample/test.txt 파일을 만들어 보자
		// 형식) new File(폴더 경로, "파일명")
		File file = new File(dir, "test.txt");
		
		// 해당 파일이 존재하지 않을 때만 생성
		if(!file.exists()) {
			try {
				file.createNewFile();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} // 실제로 파일을 만들어주는 메서드
			System.out.println("파일 생성!");
		}
		
		
	}

}

현재는 Sample이라는 폴더가 없다.
프로그램을 실행시키면
sample 폴더가 새로 생기면서
test.txt 파일도 생성된다.


예제7) 생성되어 있는 파일에 내용을 입력해보자.

import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;

public class Ex11 {

	public static void main(String[] args) {
		
		// C:/sample/test.txt 파일에 내용을 저장.
		
		try {
			FileWriter fw = new FileWriter("C:/sample/test.txt");
			
			BufferedWriter bw = new BufferedWriter(fw);
		
			bw.write("===========================");
			bw.newLine(); // 다음 줄로 이동
			
			bw.write("안녕하세요.");
			bw.newLine(); // 다음 줄로 이동
			
			bw.write("자바는 즐겁습니다.");
			bw.newLine(); // 다음 줄로 이동
			
			// 입출력 객체 닫기
			bw.close();
			fw.close();
			
			System.out.println("파일 내용 추가 완료!");

		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}

}

현재는 아무 내용이 없다.
프로그램을 실행시키면
내용이 추가되었다!