전체 방문자
오늘
어제
21종
종이의 코딩 공부방
21종
  • 분류 전체보기 (171)
    • JAVA (64)
    • Springboot (46)
      • 블로그만들기 (45)
    • Database (60)
      • Oracle (60)
    • 프로젝트 3 (CELOVER) (0)
    • 개발서버 구축 (0)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

인기 글

최근 글

최근 댓글

hELLO · Designed By 정상우.
21종

종이의 코딩 공부방

JAVA

[자바/JAVA] 프로그래밍 - IO 스트림 (Stream) 파일 읽기/쓰기 (1)

2023. 6. 16. 17:08

메모리는 휘발성임
가나다라 라고 쓰고 컴퓨터를 끄면 지워짐!! => 휘발성
기록하기 위해 파일이 필요함


간단하게 파일(file) 만들어지는 과정
java.io.File 클래스 가지고
여기서는 예외처리가 필수


 File f1 = new File();	=> 기본생성자가 없어서 오류 => 무조건 매개변수 필요함

경로 지정을 딱히 하지 않은 상태로 파일 생성 => 현재 Project 폴더에 파일 생성

File f1 = new File("test.txt");
f1.createNewFile();	// 메소드 까지 실행해야만 실제 파일이 만들어짐

존재하는 폴더에 파일 생성 => 해당 경로까지 지정

File f2 = new File("D:\\test.txt");	// "\\" 두개 쓰는 이유는 \t 가 될 수도 있음. 혹여 존재하지 않는 경로 제시시 IOException
f2.createNewFile();

파일을 만들때 폴더도 같이 만들기

File f3 = new File("D:\\temp\\test.txt");
f3.createNewFile();

폴더 먼저 만들고 파일까지 만들기 

File tempFolder = new File("D:\\temp");
tempFolder.mkdir();	// 폴더를 만들어주는 메소드 makedirectory

File f3 = new File("D:\\temp\\test.txt");
f3.createNewFile();

파일 존재여부

		System.out.println(f1.exists());	// 파일 존재여부 true/false
		System.out.println(new File("ttt.text").exists());
		
		System.out.println(f1.isFile());	// 파일이냐? true/false
		System.out.println(tempFolder.isFile());

파일명, 절대경로, 파일 용량, 상위폴더 출력

File file = new File("parent\\person.txt");
file.createNewFile();

System.out.println("파일명 : " + file.getName());	
System.out.println("절대경로 : " + file.getAbsolutePath());
System.out.println("파일 용량 : " + file.length());	// 아무것도 안써있으면 0
System.out.println("상위폴더 : " + file.getParent());

전체 코드

package com.kh.chap01_file.run;

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

public class FileRun {
	
	public static void main(String[] args) {
		
		try {	// 예외처리 필수
		// 1. 경로 지정을 딱히 하지 않은 상태로 파일 생성 => 현재 Project 폴더에 파일 생성
		File f1 = new File("test.txt");
		f1.createNewFile();	// 메소드 까지 실행해야만 실제 파일이 만들어짐
		
		// 2. 존재하는 폴더에 파일 생성 => 해당 경로까지 지정
		File f2 = new File("D:\\test.txt");	// "\\" 두개 쓰는 이유는 \t 가 될 수도 있음. 혹여 존재하지 않는 경로 제시시 IOException
		f2.createNewFile();
		
		// 3. 파일을 만들때 폴더도 같이 만들기
//		File f3 = new File("D:\\temp\\test.txt");
//		f3.createNewFile();
		
		// 3. 폴더 먼저 만들고 파일까지 만들기 
		File tempFolder = new File("D:\\temp");
		tempFolder.mkdir();	// 폴더를 만들어주는 메소드 makedirectory
		
		File f3 = new File("D:\\temp\\test.txt");
		f3.createNewFile();
		
		// 실행할때 마다 파일이 계속 만들어지나요?
		// 해당 파일 존재하면 그냥 덮어쓰기 된다. 수정사항 없으면 그대로감
		
		System.out.println(f1.exists());	// 파일 존재여부 true/false
		System.out.println(new File("ttt.text").exists());
		
		System.out.println(f1.isFile());	// 파일이냐? true/false
		System.out.println(tempFolder.isFile());

		// -----------------------------------
		
		File folder = new File("parent");
		folder.mkdir();
		
		File file = new File("parent\\person.txt");
		file.createNewFile();
		
		System.out.println("파일명 : " + file.getName());	
		System.out.println("절대경로 : " + file.getAbsolutePath());
		System.out.println("파일 용량 : " + file.length());	// 아무것도 안써있으면 0
		System.out.println("상위폴더 : " + file.getParent());
		
		} catch (IOException e) {
			e.printStackTrace();
		}
		
	}

}

실행 결과


프로그램 상에 데이터를 외부매체로 출력을 한다거나 외부매체로부터 입력을 받아올꺼임!!
반드시 그 외부매체와 통하는 통로를 만들어야됨!! 그게 바로 스트림

 

스트림(통로)의 특징

- 스트림 : 개울 / 한방향으로 흐름
- 단방향 : 입력이면 입력 / 출력이면 출력만 가능!!
   => 입력과 출력을 동시다발적으로 하고자 한다면? 입력용 스트림 / 출력용 스트림 따로 열어야됨!!
- 선입선출(FIFO) : 먼저 들어간 데이터가 먼저 나온다. // 통로가 파이프 같은 개념
- 시간지연(delay) 이라는 문제가 생길 수 있음!!

 

* 스트림의 구분

> 통로의  사이즈(1byte 짜리 / 2byte 짜리)

- 바이트 스트림 : 1byte 짜리만 왔다갔다 할 수 있을 정도의 사이즈 (좁은통로) => 입력(InputStream) / 출력(OutputStream)
- 문자 스트림 : 2byte 짜리도 왔다갔다 할 수 있을 정도의 사이즈 => 입력(Reader) / 출력(Writer)

> 외부매체에 직접 연결하는 유무
- 기반 스트림 : 외부매체와 직접적으로 연결되는 통로 (필수)
- 보조 스트림 : 말 그대로 보조 역할을 하는 통로 (속도를 빠르게 한다거나, 그 외의 유용한 기능 제공)
  보조스트림 단독으로는 사용 불가!!! 기반 스트림은 반드시 기본적으로 있어야 됨!!
  
우리는 외부매체를 파일로 해보자!!
첨부파일 기능 구현할 때 필요한 개념!!


바이트 기반 스트림

 

"바이트 기반 스트림" 가지고 데이터 입출력해보기!!

- 바이트 스트림 : 데이털르 1바이트 단위로 전송하는 통로(좁은 통로임..1바이트면 한글 깨짐)
- 기반 스트림 : 외부매체와 직접적으로 연결되는 통로

XXXInputStream : XXX 매체로부터 데이터를 입력 받는 통로 (외부매체로부터 데이터 읽어오겠음!)
XXXOutputStream : XXX 매체로 데이터를 출력하는 통로 (외부매체로부터 데이터를 내보내겠다. 쓰겠다.)

 

바이트 기반 스트림으로 파일 쓰기

package com.kh.chap02_byte.model.dao;

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

public class FileByteDao {

    // 프로그램 (자바 또는 메모리) --------> 외부매체(파일) (출력 : 프로그램 상의 데이터를 파일로 내보내기, 즉 파일로 저장)
    public void fileSave() {

        // FileOutputStream : 파일과 직접적으로 연결해서 1바이트 단위로 출력하는 스트림

        // 1. 스트림 생성 (통로 만들기)
        // 2. 스트림으로 데이터를 출력 (매소드 활용)
        // 3. 다 사용한 후 스트림 반납

        FileOutputStream fout = null;
        try {
            // 1. FileOutputStream 객체 생성 => 해당 파일과의 연결 통로 만들어짐
    //		fout = new FileOutputStream("a_byte.txt"/*, false*/);	// 파일없으면 생성하고 있으면 덮어쓰기
            fout = new FileOutputStream("a_byte.txt", true);	// 이전파일에 이어서 쓰기

            /*
             * true 미작성시 => 해당 파일이 존재할 경우 기존의 데이터 덮어 씌워짐(기본값이 false)
             * true 작성시 => 해당 파일이 존재할 경우 기존의 데이터에 이어서 작성
             */

            // 2. 파일에 데이터를 출력하고자 할 때 writer 메소드 사용
            //	  숫자를 출략하든 문자를 출력하든 실상 파일에 기록되는건 문자로 기록됨
            fout.write(97);	// 'a'가 저장됨
            fout.write('b');	// 'b'가 저장됨
    //		fout.write('헐');	// 한글은 2byte 짜리여서 깨져서 저장됨 => 바이트 스트림으로는 제한이 있음

    //		fout.write(byte[] b);
            byte[] arr = {99, 100, 101};
            fout.write(arr);	// cde 문자가 저장

    //		fout.write(byte[] b , int off, int len); : byte배열의 off 인덱스부터 len개수 만큼 출력
            fout.write(arr, 1, 2);	// de 문자가 저장

            // 3. 스트림 이용했으면 반납하기!(반드시)
    //		fout.close(); // 위에서 write() 메소드 실행시 IOException 발생했을 경우 => catch 블럭 실행 후 빠져나갈꺼임 (반납하는 코드 실행안됨!)
                          // 반드시 실행해야하는 구문이기 때문에 finally{}에 기술

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {	// 이 안에 작성된 코드는 어떤 예외가 발생했던간에 마지막에 무조건 실핼하고 빠져나갈꺼임
            try {
                // 3. 스트림 다 이용했으면 반납하기!! (반드시)
                fout.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }
}

실행 Class

package com.kh.chap02_byte.run;

import com.kh.chap02_byte.model.dao.FileByteDao;

public class FileByteRun {

	public static void main(String[] args) {

		FileByteDao dao = new FileByteDao();
		dao.fileSave();
	}
}

실행 결과


바이트 기반 스트림으로 파일 읽기

package com.kh.chap02_byte.model.dao;

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

public class FileByteDao {

    // 프로그램 <----- 파일 (입력 : 파일로부터 데이터 가져오기)
    public void fileRead() {

        // FileInputStream : 파일로부터 데이터를 1바이트 단위로 입력받는 스트림

        // 1. 스트림 생성(통로 만들기)
        // 2. 스트림 통해서 입력받아옴 (메소드 활용)
        // 3. 스트림 반납

        FileInputStream fin = null;

        try {
            // 1. FileInputStream 객체생성 => 해당 파일과 연결 통로 만들어짐
            fin = new FileInputStream("a_byte.txt");

            // 2. 파일로부터 데이터를 읽어들이고자 할 때 read 메소드 사용
            // 		1byte 단위로 하나씩 읽어옴 / 반환형이 int 여서 숫자로 읽어들임

            /*
            System.out.println(fin.read());	// a
            System.out.println(fin.read());	// b
            System.out.println(fin.read());	// c
            System.out.println(fin.read());	// d
            System.out.println(fin.read());	// e
            System.out.println(fin.read());	// d
            System.out.println(fin.read());	// e
            System.out.println(fin.read());	// 파일의 끝을 만나는 순간 -1을 받아오는거 확인
            */

            // 실제로 파일에 얼마만큼의 데이터가 있는지 모를 경우 => 반복문 활용

            /* 반복문 수행시 매번 read()가 두번씩 실행되기 때문에 퐁당퐁당 읽어들여짐 => 잘못됨
            while(fin.read() != -1) {	// 읽어들인 값이 -1이 아닐 경우에만 반복적으로 실행하도록 << 여기서 한번읽고
                System.out.println(fin.read());		// << 여기서 두번째 읽음
            }
            */

            // read() 호출 반복문 수행시에만 실행되도록
            // 해결방법1. 무한반복을 돌리면서 매번 조건검사
			/*
            while(true) {
                int value = fin.read();
                if(value == -1) {
                    break;
                }
                System.out.println(value);
            }
			*/
            // 해결방법2. 권장방법
            int value = 0;
            while((value = fin.read()) != -1){
                System.out.println((char)value);
            }

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 3. 다 사용한 스트림 반납
            try {
                fin.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

실행 Class

package com.kh.chap02_byte.run;

import com.kh.chap02_byte.model.dao.FileByteDao;

public class FileByteRun {

	public static void main(String[] args) {

		FileByteDao dao = new FileByteDao();
		dao.fileRead();
	}
}

실행 결과


문자 기반 스트림

 

"문자 기반 스트림"을 가지고 입출력 해보기

- 문자스트림 : 데이터를 2바이트 단위로 전송하는 통로다 (넓은 통로)
- 기반스트림 : 외부매체와 직접적으로 연결되는 통로다

 

- XXXReader : 입력용 스트림
- XXXWriter : 출력용 스트림

 

문자 기반 스트림으로 파일 쓰기

package com.kh.chap03_char.model.dao;

import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

// dao (Data Access Object)
public class FileCharDao {
	
	// 프로그램 --------> 파일(출력)
	public void fileSave() {
		// FileWriter : 파일로 데이터를 2바이트 단위로 출력할 수 있는 스트림
		
		FileWriter fw = null;
		
		try {
			// 1. FileWriter 객체 생성
			fw = new FileWriter("b_char.txt"/*, true */);	// 해당 파일이 없으면 새로 만들고 연결, 있으면 그냥 연결
			
			// 2. write 메소드를 이용해서 데이터 출력
			// 		2byte 단위로 데이터 전송
			
			fw.write("와! IO 재밌다..ㅎ");
			fw.write(' ');
			fw.write('A');
			fw.write('\n');
			fw.write('ㅎ');
			
			char[] arr = {'a', 'p', 'p', 'l', 'e'};	// 통로만 2byte 이고 실제롤 하나씩 전달
			fw.write(arr);
			
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				// 3. 스트림 반납
				fw.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
}

실행 Class

package com.kh.chap03_char.run;

import com.kh.chap03_char.model.dao.FileCharDao;

public class FileCharRun {

	public static void main(String[] args) {
		
		FileCharDao dao = new FileCharDao();
		dao.fileSave();
//		dao.fileRead();
	}
}

실행 결과


문자 기반 스트림으로 파일 읽기

package com.kh.chap03_char.model.dao;

import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

// dao (Data Access Object)
public class FileCharDao {

	// 프로그램 <--------- 파일 (입력)
	public void fileRead() {
		
		// fileReader : 파일로부터 데이터를 2바이트 단위로 입력받을 수 있는 스트림이다.
		FileReader fr = null;
		
		try {
			// 1. FileReader 객체 생성
			fr = new FileReader("b_char.txt");
			
			// 2. read 메소드 이용해서 읽어들이자(정수값)
			// 	  파일의 끝을 만나는 순간 -1 출력
			
			int value = 0;
			while((value = fr.read()) != -1) {
				System.out.println((char)value);
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				fr.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
}

실행 Class

package com.kh.chap03_char.run;

import com.kh.chap03_char.model.dao.FileCharDao;

public class FileCharRun {

	public static void main(String[] args) {
		
		FileCharDao dao = new FileCharDao();
		dao.fileSave();
//		dao.fileRead();
	}
}

실행 결과

    'JAVA' 카테고리의 다른 글
    • [자바/JAVA] 프로그래밍 - 컬렉션(Collection)_ArrayList
    • [자바/JAVA] 프로그래밍 - IO 스트림 (Stream) 파일 읽기/쓰기 (2)
    • [자바/JAVA] 프로그래밍 - API_실습 문제 (2)
    • [자바/JAVA] 프로그래밍 - 예외처리(Exception)
    21종
    21종
    코딩 공부한 것 정리하려고 만든 블로그

    티스토리툴바