Java I/O - 파일 복사하기

BufferedReaderBufferedWriter를 이용하여 파일을 복사하는 과정을 정리해보았다.

  1. 애국가가 작성된 파일을 인텔리제이 프로젝트 디렉토리에 넣어둔다.
  2. 이 파일을 복사하는 메서드를 생성한다.
  3. 이렇게 복사한 파일을 새로운 파일로 생성하는 메서드를 생성한다.
  4. 실행하여 파일이 복사되는지 확인한다. 만약 파일이 이미 존재한다면, Exception을 발생시킨다.

파일을 복사하는 메서드 개발

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
/**
* 파일 읽어들이는 메서드
*
* @param filename
* @param size
* @return
* @throws IOException
*/
static String inputWord(String filename, int size) throws IOException {
File file = new File(filename); // 파일존재유무 파악을 위한 File 객체 생성
String str = "";
if(file.exists()){ // 파일이 존재하는지 확인
try(BufferedReader reader = new BufferedReader(new FileReader(filename))){ // try-with-resource 사용
for (int i = 0; i < size; i++) {
String temp = reader.readLine(); // 한줄씩 Buffer에 read
if(temp!=null){
str += "\n"+temp; // 한줄씩 끊어서 String형 변수에 저장
} else { // 더이상 읽을 문자열이 없으면 종료
break;
}
}
}
return str;
} else {
throw new IOException("파일이 없는데요?"); // 파일이 존재하면 Exception 발생
}
}

먼저 복사하려는 대상 파일이 존재하는지 확인부터 했다.

1
2
File file = new File(filename);
if(file.exists()) { }

File 클래스엔 .exists() 라는 함수가 있는데, 이걸로 파일이 존재하는지 여부를 boolean 타입으로 반환받을 수 있다. 복사대상 파일이므로, 복사대상이 존재하지 않으면 조건절 분기처리로 IOException을 발생시켰다.

파일이 존재하지 않는다면, try-resource-with 를 작동시킨다.

1
try(BufferedReader reader = new BufferedReader(new FileReader())) { }

일반적으로 IO와 관련한 클래스는 사용한 직후에 .close() 를 사용해야 하는데, try-resource-with 를 사용하면 .close() 를 개발자가 닫을 필요없이 알아서 닫힌다. 자바8에서 추가된 기능이다.

파일을 읽어들이는 클래스인 FileReader를 파라미터로 받는 BufferedReader 객체를 생성했다.

이제 문자열 변수에 BufferedReader 클래스의 readLine()을 이용하여 한줄씩 읽어들인다.

1
2
3
4
5
6
7
8
for (int i = 0; i < size; i++) {
String temp = reader.readLine(); // 한줄씩 Buffer에 read
if(temp!=null){
str += "\n"+temp; // 한줄씩 끊어서 String형 변수에 저장
} else { // 더이상 읽을 문자열이 없으면 종료
break;
}
}

이 때 문자열 변수를 2개(str, temp)를 생성했는데, temp는 실제 readLine() 을 이용하여 버퍼에 읽어들인 데이터를 임시저장하는 변수이고, strtemp에 데이터가 있을경우, 즉 데이터가 읽어들여졌을경우 이어붙여서 저장하고 최종적으로 메서드의 반환타입으로 반환될 변수이다.

만약 버퍼에 읽어들인 데이터가 없을 경우는 for 문을 종료하도록 했다.



파일을 생성하는 메서드 개발

파일을 읽어들이는 메서드를 생성했으므로 이제 복사하는 기능은 개발되었다. 이렇게 복사한 데이터를 새로 생성한 파일에 작성(Writer)하여 최종적으로 복사본을 생성하는 메서드를 개발할 차례이다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/**
* 파일 생성(출력)하는 메서드
*
* @param filename
* @param target
* @param size
* @throws IOException
*/
static void createCloneFile(String filename, String target, int size) throws IOException {
File file = new File(filename); // 파일존재유무 파악을 위한 File 객체 생성
if(file.exists()){ // 파일이 존재하는지 확인
throw new IOException("같은 이름의 파일이 이미 존재합니다.");
} else {
try(BufferedWriter newFile = new BufferedWriter(new FileWriter(filename))){
newFile.write(inputWord(target, size)); // inputWord()로 파일을 읽어들이고, 새 파일로 복제
}
}

이번에도 파일 존재유무를 확인하고, 파일이 존재하면, IOException 을 발생시켰다. 이번엔 위와 다르게 했는데 이유는 새로운 파일을 생성해야하는데, 파일이 이미 존재하면 파일을 덮어씌워지는 의도하지 않은 상황이 발생할 수 있으므로 .exists() 에서 true를 반환할경우 IOException을 발생시켰다.

그리고 이번에도 try-resource-withBufferedWriter 객체를 생성했다.

1
try(BufferedWriter newFile = new BufferedWriter(new FileWriter(filename))) { }

이렇게 생성한 BufferedWriter 객체에 작성할 데이터는 위에서 만들어놓은 inputWord()를 이용하여 데이터를 입혔다. 이제 파일을 복사하고 복사본 파일을 생성하는것까지 구현하였다.


메인 메서드 개발

이제 위에서 만든 메서드를 실행하는 메인 메서드를 개발할 차례이다.

1
2
3
4
5
6
7
8
9
10
11
12
public static void main(String[] args) throws IOException {

String target = "korean.txt";
String cloneFile = "clone.txt";

// 타겟 대상 파일 읽어들여서 콘솔에 출력하기
String fileread = inputWord(target, 1000);
System.out.println(fileread);

// 파일 읽어들여서 다른이름의 파일 생성하기
createCloneFile(cloneFile, target, 1000);
}

"korean.txt" 라는 이름의 파일을 복사할 것이고, 이렇게 복사해서 새로 생성될 파일 이름은 "clone.txt" 이다.

사실 콘솔에서 확인하기 위하여 몇 줄 더 작성하긴 했지만, 메인 메서드에서 중요한 코드는 마지막 한 줄이다.

1
createCloneFile(cloneFile, target, 1000);

target 파일을 1000줄까지 읽어들이고, cloneFile을 생성하라는 코드이다.


파일 복제 테스트

정상적으로 복사본이 생성되었다면 아래와 같은 화면을 볼 수 있을 것이다.

만약 이미 같은 이름의 파일이 존재한다면 아래와 같이 IOException이 발생한걸 확인할 수 있다.

이 코드 내용은 Github Gist에 공개해두었다.