Java

File I/O로 파일 복사하기

검정콩 2022. 5. 6. 14:40

File클래스는 파일 크기, 파일 속성 등과 같은 파일의 정보를 얻어내는 기능과 파일 생성/삭제 기능을 제공한다.

File IO를 이용해 사진 파일을 다른 폴더에 복사해넣고, 성능을 향상시켜보자.

 

c드라이브 내의 img 폴더 안에 있는 up.png 파일을 temp 폴더 안에 up_copy.png라는 이름으로 복사해 넣을 것이다.

 

 

1. 읽어오고 저장할 파일 위치 지정

1
2
String oriPath = "c:/img/up.png"
String targetPath = "c:/img/temp/up_copy.png";
cs

 

2. 파일 객체 + 스트림 준비

File file = new File(orPath); 로 파일 객체를 따로 시켜줘도 되지만 코드를 단순화시키기 위해 파일위치를 바로 스트림에 집어넣어 준다.

1
2
FileInputStream input = new FileInputStream(oriPath);
FileOutputStream output = new FileOutputStream(targetPath);
cs

우선 파일을 읽기 위해 FileInputStream 클래스를 가져온다.

그 다음, InputStream과 OutputStream을 객체화하여 input과 output 에 넣어준다. 이 과정에서 오류가 뜰 수 있는데, try catch로 처리해줘도 되지만 코드가 복잡해지는게 싫었기에 그냥 throws 해주었다.

 

3. 스트림을 통해 파일 읽어오기

1
2
3
4
5
6
7
8
int data;
int count = 0;
while ((data = input.read()) != -1) {
  //파일 내보내기
output.write(data);
    count ++;
    System.out.println("복사중 : "+count);
    }
System.out.println("파일 복사 완료!");
cs

read() 메서드는 파일로부터 1바이트씩 읽어온 값을 반환한다. 이제 input.read()를 data에 넣어 while 구문을 돌린다.파일을 더이상 읽을 수 없을 때까지(EOF, -1) 반복문이 실행된다.

반복문 속 write() 메서드를 통해 input에서 읽어온 값을 사용할 것이며, up.png 파일을 복사하는 과정을 표현하기 위해 읽어들이는 바이트의 숫자를 매겨준다. count 변수를 선언하여 while문이 멈추기 전까지 count의 수가 1씩 증가하도록 한다.

 

코드 실행시 1025936의 숫자가 매겨지며 파일 복사가 완료된다. 파일을 복사하는데 바이트를 1025936번이나 옮겼다는 의미이다. 이 횟수를 줄이려면(성능을 향상시키려면) 한번에 1바이트씩 옮길게 아니라 한꺼번에 많은 양의 바이트를 옮기면 된다.

 

4. 속도 향상

바이트를 배열로 만들어 1바이트씩이 아닌 1024 바이트씩 읽어들이도록 성능을 향상시켜보겠다. byte 배열 arr를 선언해준 뒤, 위와 마찬가지로 while 반복문을 실행해준다.

1
2
3
4
5
6
7
8
9
10
byte[] arr = new byte[1024];
while(input.read(arr) != -1) { //읽어오는 내용을 arr에 담는다.
    output.write(arr);
    //write()메서드의 타입이 byte로 되어있는 것을 선택해 arr를 넣어준다.
    count++;
    //읽어들이는 바이트의 수를 비교하기 위하여 count로 숫자를 매겨준다.
    System.out.println("복사중 : "+count);
}
        
System.out.println("파일 복사 완료!");
cs

실행시 바이트를 세는 횟수가 획기적으로 줄어든 것을 확인할 수 있다.

temp 폴더 안에도 파일이 무사히 복사된 것을 확인할 수 있다.

 

5. 사용한 자원 반납(flush, close)

OutputStream 은 flush()메서드로 꼭 닫아주어야 한다. 시스템 자원을 끌어다 쓰는 것이기 때문에 flush와 close로 자원을 다 썼다고 시스템에 신호를 보내줘야 한다.

1
2
3
output.flush();
input.close();
output.close();
cs