어제 오늘 내일

[Java] 파일 복사하기 본문

IT/Java

[Java] 파일 복사하기

hi.anna 2021. 6. 7. 08:04

 

Java에서 파일을 다루는 방법을 알아보고 있습니다.

[Java] 텍스트 파일 읽기 ( FileReader, BufferedReader, Scanner, Files )

[Java] 파일 생성하는 3가지 방법 (File, FileOutputStream, Files)

[Java] 파일, 디렉토리 존재 여부 확인하기

[Java] 파일에 텍스트 쓰기

[Java] 파일, 디렉토리 삭제하기

[Java] 현재 디렉토리 가져오기

[Java] 파일 사이즈 구하는 3가지 방법

[Java] 디렉토리 생성하기

[Java] 파일 또는 디렉토리 생성일자 구하기

[Java] 파일의 최종 수정일자 조회

[Java] 파일 최종수정일자 변경하기

[Java] Text 파일 라인수 세기

[Java] 텍스트 파일의 마지막 라인부터 읽기

[Java] 파일 특정 라인 읽기

 

 

이번에는 파일을 복사하는 방법을 소개합니다.

  1. FileInputStream, FileOutputStream
  2. Files.copy()
  3. FileChannel
  4. Apache Commons IO

 

 

1. FileInputStream, FileOutputStream

FileInputStream으로 파일을 읽고, FileOutputStream으로 새로운 파일을 씁니다.

 

  예제  

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

public class CopyFile {
    public static void main(String[] args) throws IOException {

        // 1. 원본 File, 복사할 File 준비
        File file = new File("D:\\example\\text_file.txt");
        File newFile = new File("D:\\example\\new_text_file.txt");

        // 2. FileInputStream, FileOutputStream 준비
        FileInputStream input = new FileInputStream(file);
        FileOutputStream output = new FileOutputStream(newFile);

        // 3. 한번에 read하고, write할 사이즈 지정
        byte[] buf = new byte[1024];

        // 4. buf 사이즈만큼 input에서 데이터를 읽어서, output에 쓴다.
        int readData;
        while ((readData = input.read(buf)) > 0) {
            output.write(buf, 0, readData);
        }

        // 5. Stream close
        input.close();
        output.close();
    }
}

readData = input.read(buf);

buf(버퍼)에 데이터를 읽어서 넣고, buf(버퍼)로 읽은 총 byte 수를 리턴합니다.

파일 끝에 도달하여, 더 이상 읽을 데이터가 없을 경우 -1을 리턴합니다.

 

output.write(buf, 0, readData);

buf(버퍼)에 담긴 데이터를,

0번째 offset부터,

readData 길이만큼,

output stream에 씁니다.

 

 

 

2. Files.copy()

java.nio.file.Files 클래스는, 파일을 복사할 수 있는 copy() 메소드를 제공합니다.

public static Path copy(Path source, Path target, CopyOption... options)

 

  파라미터  

  • source : source file path
  • target : target file path
  • options
    • REPLACE_EXISTING : target 파일이 존재하면, 덮어씁니다.
    • COPY_ATTRIBUTES : 파일 attribute를 복사합니다.
    • NOFOLLOW_LINKS : 파일이 symbolic link이면, 링크 대상이 아닌, symbolic link 자체가 복사됩니다.

 

  예제  

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;

public class CopyFile {
    public static void main(String[] args) throws IOException {

        // 1. 원본 File, 복사할 File 준비
        File file = new File("D:\\example\\text_file.txt");
        File newFile = new File("D:\\example\\new_text_file.txt");

        // 2. 복사
        Files.copy(file.toPath(), newFile.toPath(), StandardCopyOption.REPLACE_EXISTING);

    }
}

Files.copy(file.toPath(), newFile.toPath(), StandardCopyOption.REPLACE_EXISTING);

text_file.txt 파일을 new_text_file.txt로 복사합니다.

REPLACE_EXISTING 옵션을 주었기 때문에,

기존에 new_text_file.txt 파일이 존재하더라도 그대로 덮어씁니다.

 

 

 

3. FileChannel

FileChannel 클래스는 파일의 읽기, 쓰기, 맵핑 등을 위한 채널을 제공합니다.

이 클래스를 사용해서 한 파일에서 다른 파일로 컨텐츠를 전송할 수 있습니다.

 

transferFrom(), transferTo() 메소드를 이용해서 내용을 복사할 수 있습니다.

public abstract long transferFrom(ReadableByteChannel src, long position, long count)

파라미터로 전달된

src 파일채널로부터, position 위치부터, count 사이즈만큼 데이터를 복사합니다.

 

public abstract long transferTo(long position, long count, WritableByteChannel target)

파라미터로 전달된

target 파일 채널로, position 위치부터, count 사이즈만큼 데이터를 복사합니다.

 

 

  예제  

import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.channels.FileChannel;

public class CopyFile {
    public static void main(String[] args) throws IOException {

        // 1. 원본 File, 복사할 File 준비
        RandomAccessFile file = new RandomAccessFile("D:\\example\\text_file.txt", "r");
        RandomAccessFile newFile = new RandomAccessFile("D:\\example\\new_text_file.txt", "rw");

        // 2. FileChannel 생성
        FileChannel source = file.getChannel();
        FileChannel target = newFile.getChannel();

        // 3. 복사
        source.transferTo(0, source.size(), target);
        // 또는
        //target.transferFrom(source, 0, source.size());

    }
}

transferTo() 또는 transferFrom() 메소드를 이용하여 데이터를 복사할 수 있습니다.

이 메소드는 데이터를 count(source.size())만큼 target에 써주기 때문에,

만약, target 파일이 이미 존재하고, target 파일의 데이터가 더 길면,

나머지 부분은 그대로 남아있게 됩니다.

예를 들어, 아래와 같은 파일을 위 코드를 사용해서 source에서 target으로 복사한다고 해보자.

  • source 파일 : "abcd"
  • target 파일 : "efghi"

그러면 target 파일은 "abcdi"가 됩니다.

source 파일 길이의 byte만큼 target 파일에 써주었기 때문입니다.

 

 

 

4. Apache Commons IO

Apache Commons IO 라이브러리를 사용할 수도 있습니다.

FileUtils 클래스는 copyFile()이라는 메소드를 제공합니다.

public static void copyFile(File srcFile, File destFile)

 

Apache Commons IO를 사용하기 위해서는 아래 dependency를 maven에 추가해줍니다.

    <dependency>
      <groupId>commons-io</groupId>
      <artifactId>commons-io</artifactId>
      <version>2.9.0</version>
    </dependency>

 

  예제  

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

import org.apache.commons.io.FileUtils;

public class CopyFile {
    public static void main(String[] args) throws IOException {

        // 1. 원본 File, 복사할 File 준비
        File file = new File("D:\\example\\text_file.txt");
        File newFile = new File("D:\\example\\new_text_file.txt");

        // 2. 복사
        FileUtils.copyFile(file, newFile);

    }
}

FileUtils.copyFile(file, newFile);

copyFile() 메소드를 이용하여 파일을 복사하였습니다.

 


 

Java API와 Apache Commons IO 라이브러리를 이용하여

파일을 복사하는 방법을 알아보았습니다.

 

 

 

반응형
Comments