[JAVA] 파일 입출력

MINJEE·2024년 1월 8일

SMHRD_8_Java

목록 보기
4/10
post-thumbnail

🔷 입출력 스트림

  • 특징 : 기본 바이트단위, 단방향 스트림, 선입선출 구조
  • 종류 : 문자 스트림, 바이트 스트림
    • 문자 스트림 : 문자 데이터만 입출력(바이너리 데이터는 처리 불가)
      • Reader와 Writer, 하위 클래스 이름이 공통적으로 Reader/Writer로 끝남
    • 바이트 스트림 : 문자와 바이너리 데이터 처리 가능
      • InputStream과 OutputStream, 하위 클래스 이름이 공통적으로 Stream으로 끝남

아스키코드 : 문자(문자에 해당하는 아스키코드)

  • ‘0’(48), ‘1’(49), ‘2’(50), …
  • ‘A’(65), ‘B’(66), ‘C’(67), …
  • ‘a’(97), ‘b’(98), …
  • Enter키(13)
  • ctrl+Z 또는 EOP (-1) → 파일의 끝을 의미

상대 경로 와 절대 경로

  • 상대 경로 : ".\\폴더명\\파일명.확장자" (온점(.)은 현재 프로젝트폴더를 의미)
  • 절대 경로 : "c:\\폴더명\\파일명.확장자"

🔹 문자 스트림 (텍스트 파일 입출력)

  • FileReader클래스와 FileWriter 클래스 사용

파일 입력 문자 스트림

  • FileReader 변수 = new FileReader("경로/파일명.txt"); : 파일 입력 문자스트림 생성, 파일 열기
    • 변수는 클래스에 대한 레퍼런스 변수
    • FileReader 변수 = null; 파일 입력 스트림 생성 후,
      변수 = new FileReader("경로/파일명.txt"); 파일 열기 가능
  • 메소드
    • 변수.read() : 한 개의 문자를 읽어 아스키 코드(정수형) 리턴
    • 변수.read(문자형 배열변수) : 최대 배열의 크기만큼 문자들을 읽어 배열에 저장, 읽는 도중 EOF를 만나면 읽은 문자 개수 리턴
    • 변수.read(문자형 배열변수, 인덱스, 크기) : 배열변수[인덱스]부터 지정크기 개수만큼 읽어서 저장, 읽는 도중 EOF를 만나면 읽은 문자 개수 리턴 (배열변수를 미리 생성할 것!)
    • 변수.getEncoding() : 사용하는 파일의 현재 스트림이 사용하고 있는 표준 정보 반환 리턴 (ex. UTF8)
    • 변수.close() : 입력 스트림 닫기
  • 파일 입출력 동안 예외 발생 가능
    • FileNotFoundException : 파일 경로명이 틀리거나, 디스크 고장으로 파일 열기 불가
    • IOException : 디스크 오동작, 파일이 중간에 깨지거나, 디스크 공간이 모자라서 파일 입출력 불가 → try-catch 블록 반드시 필요(FileNotFoundException은 생략가능)
import java.io.FileReader;
import java.io.IOException;

public class FileReaderEx {
	public static void main(String[] args) {
		try {
			FileReader in = new FileReader(".\\src\\kr\\co\\smhrd\\traffic.csv"); //파일 입력스트림 변수명은 in
			System.out.println(in.getEncoding()); //UTF-8

			int c; //문자를 읽어 아스키코드로 반환하기 위해 int형으로 선언
			while ((c=in.read()) != -1) { // 파일 끝을 만나면 -1 리턴 
																		// => 한 문자씩 파일 끝까지 읽음!
				System.out.print((char)c); // 아스키코드를 문자형으로 출력
			}
			in.close(); // 파일 입력 스트림 닫기
		}
		catch(FileNotFoundException e) {  // 생략가능
				System.out.println("파일을 열  수 없음");
		}
		catch (IOException e) { // 반드시 필요
			System.out.println("입출력 오류");
		}
	}
}

파일 출력 문자스트림

  • FileWriter 변수 = new FileWriter("파일경로.txt"[, 추가여부]); : 파일 출력 문자스트림 생성, 파일 열기
    • 추가여부 : true이면 파일의 마지막부터 데이터 저장, false면 덮어쓰기(디폴트는 false)
  • 메소드
    • 변수.write(아스키코드); : 아스키코드(정수형)를 char로 변환하여 문자 하나를 파일에 쓰기
    • 변수.write(문자열, 위치, 개수); : 문자열[위치]부터 문자를 개수만큼 파일에 쓰기
    • 변수.write(문자형 배열변수, 인덱스, 크기); : 배열[인덱스]부터 문자를 지정된 크기 개수만큼 파일에 쓰기
    • 변수.flush(); : 스트림에 남아있는 데이터 모두 출력
    • 변수.close(); : 출력 스트림 닫기

🔹 바이트 스트림을 이용한 바이너리 파일 입출력

  • FileInputStream클래스와 FileOutputStream 클래스 사용

파일 바이트 출력 스트림

  • FileOutputStream 변수 = new FileOutputStream("파일경로"[, 추가여부]); : 파일 출력 바이트스트림 생성, 파일 열기
  • 메소드
    • 변수.write(아스키코드); : int형으로 넘겨진 한 바이트를 파일에 쓰기
    • 변수.write(바이트형 배열변수); : 배열의 바이트를 모두 파일에 쓰기
    • 변수.write(바이트형 배열변수, 인덱스, 크기); : 크기만큼 배열의 인덱스 위치부터 파일에 쓰기
    • 변수.flush(); : 출력 스트림에 남아 있는데이터 모두 출력
    • 변수.close() : 출력스트림 닫기

파일 바이트 입력 스트림

  • FileInputStream 변수 = new FileInpuStream("파일 경로") : 파일 입력 바이트스트림 생성, 파일 열기
  • 메소드
    • 변수.read() : 한 바이트를 읽어 int형으로 리턴
    • 변수.read(바이트형 배열변수) : 최대 배열의 크기만큼 배열에 저장, 읽는 도중 EOF를 만나면 읽은 바이트 수 리턴
    • 변수.read(바이트형 배열변수, 인덱스, 크기) : 최대 지정크기만큼 바이트를읽어 배열[인덱스]부터 저장, 읽는 도중 EOF를 만나면 읽은 바이트 수 리턴
    • 변수.available() : 읽을 수 있는 바이트 수 리턴
    • 변수.close() : 입력 스트림 닫기


🔷 File 클래스 : 파일의 경로명 및 속성을 다루는 클래스

  • 파일 읽기/쓰기 기능은 없음 → 파일 입출력 스트림 이용
  • 파일 객체 생성 : File 변수 = new File( );
    • File(”경로명\파일명.확장자”) : 경로와 파일명 작성
    • File(”디렉토리”, “파일”) : 폴더와 파일을 따로따로 작성 가능
  • 파일 객체의 주요 메서드
    • 변수.mkdir() : 새로운 디렉터리 생성
    • 변수.list() : 디렉터리 내의 파일과 서브디렉터리 리스트를 문자열 배열로 리턴
    • 변수.listFiles() : 디렉터리 내 파일과 서브디렉터리 리스트를 File 배열로 리턴
    • 변수.renameTo(”경로\파일명.확장자”) : 지정하는 경로명으로 파일명 변경
    • 변수.delete() : 파일/디렉터리 삭제
    • 변수.length() : 파일 크기 리턴
    • 변수.getPath() : 경로명 전체를 문자열로 리턴
    • 변수.getParent() : 파일/디렉터리의 부모 디렉터리명 리턴
    • 변수.getName() : 파일/디렉터리명 리턴
    • 변수.isFile() : 파일이면 true
    • 변수.isDirectory() : 디렉터리이면 true
    • 변수.lastModified() : 파일이 마지막으로 변경된 시간 리턴
    • 변수.exists() : 파일/디렉터리가 존재하면 true


🔷 예제 코드

🔹 예제1 : 텍스트 파일 복사

public class TextCopy {
		public static void main(String[] args) {
				File src = new File("경로명/파일명.txt"); //원본파일 경로명
				File dest = new File("경로명/파일명.txt"); //복사파일 경로명
				int c;

				try {
						FileReader fr = new FileReader(src); //파일 입력 문자스트림 생성, src파일 열기
						FileWriter fw = new FileWriter(dest); //파일 출력 문자스트림 생성, dest파일 열기
						while( (c=fr.read()) != -1 ) {
								fw.write(c); //문자 하나씩 읽고 쓰기
						}
						fr.close(); //입력스트림 닫기
						fw.close(); //출력스트림 닫기
						System.out.printIn( src.getPath() + "를 " + dest.getPath() + "에 복사");
				}
				catch (IOException e) {
						System.out.printIn("파일 복사 오류");
				}
		}
}

🔹 예제2 : 이미지 파일(바이너리 파일) 복사

public class BinaryCopy {
		public static void main(String[] args) {
				File src = new File("경로명/파일명.jpg"); //원본파일 경로명
				File dest = new File("경로명/파일명.jpg"); //복사파일 경로명
				int c;

				try {
						FileInputStream fi = new FileInputStream(src); //파일 입력 바이트스트림 생성, src파일 열기
						FileOutputStream fo = new FileOutputStream(dest); //파일 출력 바이트스트림 생성, dest파일 열기
						while( (c=fi.read()) != -1 ) {
								fo.write(c); //한 바이트씩 복사 -> 시간 오래 걸림
						}
						fi.close(); //입력스트림 닫기
						fo.close(); //출력스트림 닫기
						System.out.printIn( src.getPath() + "를 " + dest.getPath() + "에 복사");
				}
				catch (IOException e) {
						System.out.printIn("파일 복사 오류");
				}
		}
}

🔹 예제3 : 고속 복사를 위한 블록 단위 이미지파일 (바이너리 파일) 복사

public class BinaryCopy {
		public static void main(String[] args) {
				File src = new File("경로명/파일명.jpg"); //원본파일 경로명
				File dest = new File("경로명/파일명.jpg"); //복사파일 경로명
				byte[] buf = new byte[1024*10]; //10KB 버퍼

				try {
						FileInputStream fi = new FileInputStream(src); //파일 입력 바이트스트림 생성, src파일 열기
						FileOutputStream fo = new FileOutputStream(dest); //파일 출력 바이트스트림 생성, dest파일 열기
						while( true ) {
								int n = fi.read(buf); //버퍼크기만큼 읽음 (n=실제 읽은 바이트 수)
								fo.write(buf, 0, n); //buf[0]부터 n개 바이트 쓰기
								if (n<buf.length)
										break; //버퍼크기보다 작게 읽었기 때문에 복사 종료
						}
						fi.close(); //입력스트림 닫기
						fo.close(); //출력스트림 닫기
						System.out.printIn( src.getPath() + "를 " + dest.getPath() + "에 복사");
				}
				catch (IOException e) {
						System.out.printIn("파일 복사 오류");
				}
		}
}
profile
개발, 분석 배운 내용 정리하기!

0개의 댓글