자바 재귀 및 바이트 스트림을 활용한 파일 복사

재귀 이해

메소드가 자기 자신을 호출하는 프로그래밍 기법으로, 다음 주의사항이 적용됩니다:

  • 반드시 종료 조건(exit condition)이 존재해야 함
  • 호출 깊이 제한으로 스택 오버플로우 방지
  • 생성자에서는 재귀 사용 불가

기본 재귀 예제

public class RecursionExample {
    public static void main(String[] args) {
        recursiveMethod(3);
    }
    
    static void recursiveMethod(int count) {
        System.out.println("진입: " + count);
        if(count > 0) {
            recursiveMethod(count - 1);
        }
        System.out.println("탈출: " + count);
    }
}

재귀 활용 사례

1에서 N까지 합계 계산:

public class SumCalculator {
    public static void main(String[] args) {
        System.out.println(calculateSum(5)); // 15 출력
    }
    
    static int calculateSum(int num) {
        return (num == 1) ? 1 : num + calculateSum(num - 1);
    }
}

팩토리얼 계산:

public class Factorial {
    public static void main(String[] args) {
        System.out.println(computeFactorial(5)); // 120 출력
    }
    
    static int computeFactorial(int n) {
        return (n <= 1) ? 1 : n * computeFactorial(n - 1);
    }
}

피보나치 수열:

public class Fibonacci {
    public static void main(String[] args) {
        System.out.println(getFibonacci(7)); // 13 출력
    }
    
    static int getFibonacci(int pos) {
        return (pos == 1 || pos == 2) ? 1 
               : getFibonacci(pos - 1) + getFibonacci(pos - 2);
    }
}

디렉토리 탐색:

import java.io.File;

public class DirectoryTraverser {
    public static void main(String[] args) {
        traverse(new File("src"));
    }
    
    static void traverse(File dir) {
        for(File item : dir.listFiles()) {
            if(item.isDirectory()) {
                traverse(item);
            } else if(item.getName().endsWith(".java")) {
                System.out.println(item.getAbsolutePath());
            }
        }
    }
}

바이트 스트림 파일 처리

입출력 스트림은 데이터 전송을 위한 추상화된 개념으로, 다음과 같이 분류됩니다:

구분입력출력
바이트 스트림InputStreamOutputStream
문자 스트림ReaderWriter

파일 복사 구현

FileInputStream/FileOutputStream 활용:

import java.io.*;

public class FileCopier {
    public static void main(String[] args) throws IOException {
        try (
            InputStream origin = new FileInputStream("source.txt");
            OutputStream target = new FileOutputStream("target.txt")
        ) {
            byte[] buffer = new byte[1024];
            int bytesRead;
            while ((bytesRead = origin.read(buffer)) != -1) {
                target.write(buffer, 0, bytesRead);
            }
        }
    }
}

버퍼 스트림 성능 향상:

import java.io.*;

public class BufferedFileCopier {
    public static void main(String[] args) throws IOException {
        try (
            BufferedInputStream in = new BufferedInputStream(
                new FileInputStream("source.txt"));
            BufferedOutputStream out = new BufferedOutputStream(
                new FileOutputStream("target.txt"))
        ) {
            byte[] dataChunk = new byte[4096];
            int chunkSize;
            while ((chunkSize = in.read(dataChunk)) != -1) {
                out.write(dataChunk, 0, chunkSize);
            }
        }
    }
}

성능 비교

방식소요 시간
1바이트 단위 복사188ms
바이트 배열 복사1ms
버퍼 1바이트 복사6ms
버퍼 배열 복사0ms

태그: 재귀 자바입출력 FileInputStream FileOutputStream 버퍼스트림

7월 7일 00:58에 게시됨