Language/Java

파일 읽고 쓰기

느낌표 공장장 2021. 4. 2. 01:42

텍스트 파일의 내용 출력하기

FileInputStream : 파일로부터 데이터를 읽어서 이것을 입력소스로 사용할 수 있게 해주는 타입

예외처리를 해주어야한다는 안내가 뜬다
try-catch 블록처리해주었다.(alt+enter)

 

하지만 문제가 하나 발생한다. try의 중괄호 블럭 안에 FileInputStream이 선언되어 있으므로 중괄호 블록안에서만 FileInputStream을 사용할 수 있게 된다. 그렇게 된다면 중괄호 블럭 안에 모든 코드를 다 넣어야한다.

 

따라서 FileInputStream을 블럭 바깥에서 쓰기 위해 선언문을 바깥으로 옮겨준다.

완성

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.util.Scanner;

public class FileInput {
    public static void main(String[] args) {
        FileInputStream inputStream = null; // null : 아무 값도 없음
        // 이 상태로 사용하게 되면(null로) 오류가 발생하므로 꼭 값을 대입하고 난 뒤, 사용해야 한다.

        try {
            inputStream = new FileInputStream("src/chicken.txt");
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }

        // 스캐너를 생성하면서 FileInputStream을 입력 소스로 넣어주기
        Scanner scanner = new Scanner(inputStream);
        // 데이터 읽고 출력
        String line = scanner.nextLine(); 
        System.out.println(line);
        String line2 = scanner.nextLine(); 
        System.out.println(line2);
    }
}

 

하지만 두 줄만 입력되어 있는 파일을 한번 더 읽으려고(3줄을 읽으려고) 시도한다면 ? (line3 추가)

이처럼 예외가 발생하게 된다.

우리는 보통 파일에 저장된 데이터가 몇 줄인지 처음부터 알 수 없다. 따라서 반복문을 통해 출력하는 방법이 있다.

 

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.util.Scanner;

public class FileInput {
    public static void main(String[] args) {
        FileInputStream inputStream = null; // null : 아무 값도 없음
        // 이 상태로 사용하게 되면(null로) 오류가 발생하므로 꼭 값을 대입하고 난 뒤, 사용해야 한다.

        try {
            inputStream = new FileInputStream("src/chicken.txt");
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }

        // 스캐너를 생성하면서 FileInputStream을 입력 소스로 넣어주기
        Scanner scanner = new Scanner(inputStream);

        // 반복문을 통해 출력
        while (scanner.hasNextLine()) {
            String line = scanner.nextLine();
            System.out.println(line);
        }

    }
}

* scanner.hasNextLine : 어떠한 입력 소스의 다음 줄이 있는지를 판단하는 역할이다. 다음 줄이 있다면 true를 반환하고 없다면 false를 반환한다. (이를 통해 다음 줄이 존재하는 동안만 데이터를 읽게 된다)


텍스트 파일로 저장하기

파일을 쓰기 위해서는 많은 방법이 있지만 여기서는 FileWriter 사용

 

* e.printStackTrace : 에러를 출력. try-catch를 사용해서 예외 처리를 할 때에는 catch 블록에서 적절한 처리를 해주어야한다.

 

여기서는 위의 파일 읽기처럼 e.printStackTrace(); 만 작성한다면, 에러를 출력하고 지나치게 되므로 try-catch 블록 아래에서 FileWriter를 사용하는 부분에서 또다시 예외가 발생하게 된다. 그러므로 e.printStackTrace를 치우고 적절한 처리를 해준다.

import java.io.FileWriter;
import java.io.IOException;
import java.util.Scanner;

public class FileOutput {
    public static void main(String[] args) {
        FileWriter writer = null;
        try {
            writer = new FileWriter("src/output01.txt", true);
        } catch (IOException e) {
            System.out.println("파일 생성에 실패했습니다.");
            // exit를 호출하여 프로그램 종료
            System.exit(1);
        }

        // 사용자가 입력한 문자열 파일에 쓰기
        // 1. 스캐너 만들기
        Scanner scanner = new Scanner(System.in);

        System.out.println("종료하려면 입력 없이 엔터를 누르세요.");

        // 2. 입력 받고 파일에 쓰기 반복
       while (true) {
           String input = scanner.nextLine();

           // 빈문자열(엔터)을 입력받았을 때 종료하도록
           if (input.equals("")) {
               System.out.println("파일 입력을 종료합니다.");
               break;
           }

           try {
               // 각각 입력받은 문자열들 줄바꿈
               writer.write(input + "\n");
           } catch (IOException e) {
               System.out.println("파일에 데이터를 쓰는 데에 실패했습니다.");
               System.exit(2);
           }
       }

        try {
            writer.close();
        } catch (IOException e) {
            System.out.println("파일 닫기에 실패했습니다.");
        }
    }
}

* System.exit : 프로그램을 종료시킨다. exit안에 들어가는 숫자 중 0은 일반적으로 프로그램이 정상적으로 종료 되었음을 의미한다.

만약 exit를 호출하면서 1을 넣어주게 되면 종료 코드에 1이라는 것이 찍히고 프로그램이 정상적으로 종료되지 않았다는 것을 알 수 있다.

 

* FileWriter.write : 파일에 문자열을 쓸 수 있다. (예외처리 필요)

  •  ⚠︎ 파일을 다 사용한 뒤에는 .close를 해주어야한다. 이는 '이 파일을 다 사용했으니 파일의 변경 내용을 반영하고, 파일을 닫겠다.'라는 의미가 된다. (close를 사용하지 않으면 파일에 쓴 내용들이 반영되지 않을 수 있다.
  • FileWriter는 기본적으로 데이터를 한줄로 쓰게 되어있다. 줄바꿈을 하고 싶으면 줄바꿈 문자를 통해 줄바꿈을 한다.
  • 만약 내용을 수정하여 코드를 여러번 실행시켜도 마지막에 썼던 데이터만 들어가게 된다. (여러번 쓰이지 X) 이것 또한 File.writer의 기본 동작이 파일을 덮어쓰는 것이기 때문이다. 
    • 파일의 뒤에 데이터를 계속 추가하고 싶다면 FileWriter를 생성할 때 true 옵션을 주어야 한다. 


간단 메모장 만들기

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Scanner;

public class Notepad {
    public static void main(String[] args) {
        // 사용자 입력을 위해 스캐너 생성
        Scanner scanner = new Scanner(System.in);

        // 메모 읽고 쓰기 반복
        while (true) {
            System.out.println("원하는 작업 번호를 입력해주세요.");
            System.out.println("1. 메모 읽기");
            System.out.println("2. 새 메모");
            System.out.println("3. 종료");

            // 작업번호를 입력할 변수
            int taskNum;

            // 번호 입력받아 taskNum에 넣기
           try {
                String input = scanner.nextLine();
                taskNum = Integer.parseInt(input);
            } catch (NumberFormatException e) {
               // 예외처리 (번호 아닌것 입력했을 경우)
               System.out.println("잘못된 입력입니다.");
               // 반복문의 처음으로 돌아감
               continue;
           }

           if (taskNum == 1) {
               System.out.println("메모 파일명을 입력하세요.");

               String fileName = scanner.nextLine();

               FileInputStream inputStream = null;

               try {
                   inputStream = new FileInputStream(fileName);
               } catch (FileNotFoundException e) {
                   System.out.println("파일이 존재하지 않습니다.");
                   continue;
               }

               System.out.println(fileName + "의 내용을 출력합니다.");

               // 파일의 내용 읽기 위해 스캐너 생성
               Scanner reader = new Scanner(inputStream);

               // 한 줄씩 읽어오기 반복
               while (reader.hasNextLine()) {
                   System.out.println(reader.nextLine());
               }
               System.out.println("\n");

               reader.close();
           }

           else if (taskNum == 2) {
               System.out.println("저장할 메모 파일명을 입력하세요.");

               String fileName = scanner.nextLine();

               FileWriter writer = null;

               try {
                   writer = new FileWriter(fileName);
               } catch (IOException e) {
                   System.out.println("파일 생성에 실패했습니다.");
                   continue;
               }

               System.out.println("메모할 문자열을 입력하세요.");
               System.out.println("종료: 빈 줄에서 엔터 입력");

               while (true) {
                   String input = scanner.nextLine();

                   if (input.equals("")) {
                       break;
                   }

                   try {
                       writer.write(input);
                       writer.write("\n");
                   } catch (IOException e) {
                       System.out.println("파일에 문자열을 입력하지 못했습니다.");
                   }
               }

               try {
                   writer.close();
               } catch (IOException e) {
                   System.out.println("파일을 닫는 데 실패했습니다.");
               }
           }

           else if (taskNum == 3) {
               System.out.println("프로그램을 종료합니다.");
               break;
           }

           else {
               System.out.println("잘못된 입력입니다.");
           }
        }
    }
}

 

 

 

 

유투브 "초간단 자바"님 영상을 통해 공부한 내용입니다 !
www.youtube.com/watch?v=248siBB69So&t=1s

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

  (0) 2021.04.29
메소드  (0) 2021.04.28
숫자 맞추기 게임 만들기  (0) 2021.03.31
배열  (0) 2021.03.31
반복문  (0) 2021.03.30