농장/Java·Kotlin

java.io.File 특정 파일만 파일 생성 안될 때 해결 - 논리오류 고치기

귤발자 2020. 7. 29. 12:19
728x90
반응형

한 프로젝트 폴더 내 특정 클래스 속 파일만 생성이 안되면 프로젝트 폴더의 문제가 아니다.

그냥 잘못 코드를 잘못 작성한거다.

 

 

※아래 내용은 모두 필자의 지식+뇌피셜이니 100% 신뢰하지 마십시오.

 

 

예시 코드를 만들어왔다. 이미 존재할 가능성이 큰 상태의 파일을 생성한 후, 그 파일의 내용을 읽어들여 새로 생성한 또다른 파일에 작성하는 파일내용복사 목적의 코드이다. 

이 코드는 오류를 발생시킨다.

우선, 자바의 File에 대해 알아보면

  • new File() 은 파일의 경로를 지정시켜주는 것이 주 목적이다. 
  • 파일 생성 시 기존에 존재하는 파일이면 새로 생성하지 않는다.

아래 10행에선 해당 파일이 이미 존재할 것이란 가정하에 파일을 생성한 후 곧바로 14행에서 파일을 읽어들이는데, 만약 test.txt 파일이 존재하지 않아 오류를 발생시킨 것이다.

 

public class FileReaderEx {
    public static void main(String[] args) {
        String line = "";
        FileReader fr = null;
        BufferedReader br = null;
        FileWriter fw = null;
        BufferedWriter bw = null;
        
        //생성할 파일(이미 존재할 가능성 있음)
        File file1 = new File("test.txt");
        
        //test.txt 파일 내용을 읽어오는 스트림 생성
        try {
            fr = new FileReader(file1);
        } catch (FileNotFoundException e2) {
            e2.printStackTrace();
        }
        br = new BufferedReader(fr);
        
        //생성할 파일
        File file2 = new File("print.txt");

        //print.txt 파일에 내용을 작성하는 스트림 생성
        try {
            fw = new FileWriter(file2, true);
        } catch (IOException e1) {
            e1.printStackTrace();
        }
        bw = new BufferedWriter(fw);
        
        //test.txt 파일에서 읽어온 내용을 print.txt에 작성
        try {
            while(true) {
                line = br.readLine();
                if(line==null) break;
                bw.write(line);
                bw.newLine();
            }
            bw.flush();
            br.close(); bw.close();
            fr.close(); fw.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
​

 

java.io.FileNotFoundException: test.txt (지정된 파일을 찾을 수 없습니다)

 

 

컴파일 테스트를 해보았다.

  • test.txt 파일 미존재 시 -> 오류
  • test.txt 파일 존재 + 내용 없을 시 -> 오류 없이 실행
  • 10줄의 코드만 실행(=파일만 생성) -> 오류 없이 실행되나 파일이 생성되지 않음

위 코드 실행 전 파일 탐색기나 개발 툴 내에서 직접 test.txt를 생성한 후(내용X) 실행하면 오류가 발생하지 않는데

test.txt 파일을 코드 내에서 생성한 후(역시 내용X) 실행하면 왜 오류가 나는가?

아마 그 이유는 내가 위에서 'new File() 은 파일의 경로를 지정시켜주는 것이 주 목적이다'라고 하였는데, 이것과 관련이 있지 않나 싶다.

 

코드에서 완전히 새로운 파일을 생성하고자 할때, 실존하지 않는 파일이기 때문에 코드내에서 곧바로 내용을 작성해주지 않으면 컴파일러는 이것을 가상의 파일이라고 생각하여 실존하지 않는다고 생각하는 것 같다. 위 코드에선 test.txt 파일이 실존하지 않을때 해당 파일과 같은 이름으로 파일을 생성하고 곧바로 읽어들이려고 했기 때문에 컴파일러가 가상의 파일이라 생각하여 '존재하지 않는 파일'이라는 오류를 발생시킨 것이다.

 

 

 

해결 방법1. 14-21줄

파일을 생성할 경우 곧바로 내용을 작성해준다. 해당 파일과 그 내용이 이미 존재할 경우라도 괜찮다. 해당 파일에 적혀있을(또는 적혀있어야할) 내용을 작성시키되 덮어쓰기하도록(결국 코드 실행전과 test.txt 파일의 내용이 바뀌지 않는다) FileWriter생성 시 내용추가여부를 false로 지정한다.

 

import java.io.*;

public class FileReaderEx {
    public static void main(String[] args) {
        String line = "";
        FileReader fr = null;
        BufferedReader br = null;
        FileWriter fw = null;
        BufferedWriter bw = null;
        
        //생성할 파일(이미 존재할 가능성 있음)
        File file1 = new File("test.txt");
        
        //test.txt 내용 작성
        try {
            fw = new FileWriter(file1, false);
            fw.write("What should I do is always study.\nhehe");
            fw.flush();
        } catch (IOException e3) {
            e3.printStackTrace();
        }
        
        //test.txt 파일 내용을 읽어오는 스트림 생성
        try {
            fr = new FileReader(file1);
        } catch (FileNotFoundException e2) {
            e2.printStackTrace();
        }
        br = new BufferedReader(fr);
        
        //생성할 파일
        File file2 = new File("print.txt");

        //print.txt 파일에 내용을 작성하는 스트림 생성
        try {
            fw = new FileWriter(file2, true);
        } catch (IOException e1) {
            e1.printStackTrace();
        }
        bw = new BufferedWriter(fw);
        
        //test.txt 파일에서 읽어온 내용을 print.txt에 작성
        try {
            while(true) {
                line = br.readLine();
                if(line==null) break;
                bw.write(line);
                bw.newLine();
            }
            bw.flush();
            br.close(); bw.close();
            fr.close(); fw.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}​

 

 

해결방법2. 14-23줄

방법1과 맥락은 비슷하지만 컴파일러에겐 이것이 훨씬 좋은 코드이다. test.txt 내용추가 코드를 필요하지 않을 땐 실행하지 않아도 되기 때문이다.

 

import java.io.*;

public class FileReaderEx {
    public static void main(String[] args) {
        String line = "";
        FileReader fr = null;
        BufferedReader br = null;
        FileWriter fw = null;
        BufferedWriter bw = null;
        
        //생성할 파일(이미 존재할 가능성 있음)
        File file1 = new File("test.txt");
        
        //test.txt 미존재시 새로 작성
        if(!file1.exists()) {
            try {
                fw = new FileWriter(file1);
                fw.write("What should I do is always study.\nhehe");
                fw.flush();
            } catch (IOException e3) {
                e3.printStackTrace();
            }
        }
        
        //test.txt 파일 내용을 읽어오는 스트림 생성
        try {
            fr = new FileReader(file1);
        } catch (FileNotFoundException e2) {
            e2.printStackTrace();
        }
        br = new BufferedReader(fr);
        
        //생성할 파일
        File file2 = new File("print.txt");

        //print.txt 파일에 내용을 작성하는 스트림 생성
        try {
            fw = new FileWriter(file2, true);
        } catch (IOException e1) {
            e1.printStackTrace();
        }
        bw = new BufferedWriter(fw);
        
        //test.txt 파일에서 읽어온 내용을 print.txt에 작성
        try {
            while(true) {
                line = br.readLine();
                if(line==null) break;
                bw.write(line);
                bw.newLine();
            }
            bw.flush();
            br.close(); bw.close();
            fr.close(); fw.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}​

 

기본적인 문법이지만 나처럼 헤맸을 사람이 분명이 있을 거라 생각하여 작성한 글이다.

728x90
반응형