자바로 파일 재귀 탐색


자바로 파일 입출력을 수행하면 여러 개의 파일을 순차적으로 탐색하면서 파일 입출력을 수행하는 경우가 존재한다. 그러기 위해서는 일일이 파일의 모든 경로를 넣어주는 것이 효과적이라고 보기 어렵다.


수 많은 파일들을 순차적으로 탐색한다면 어떻게 하는 것이 효율적일까? 라는 의문에 내가 할 수 있는 대답은 재귀호출 메소드를 만들어 디렉토리를 계속해서 탐색해나가는 방법이 최적이라고 생각된다. 


폴더 및 파일 구조

아래의 내용을 살펴보면, E: 드라이브 하위에 "folder: 라는 디렉토리가 존재하고 "folder" 디렉토리 하위에는  A_Dir, B_Dir, C_Dir, D_Dir 이라는 디렉토리가 다시 존재하고 있다.


그리고 A_Dir 디렉토리 안에 들어가면 Hello, 고구마, 독수리, 토마토 라는 이름을 텍스트 파일이 존재한다. 토마토라는 텍스트 파일을 열면 아래와 같이 "토마토 텍스트 파일" 이라는 문구가 적혀있다.

 



탐색로직

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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
package edu.doubler.blog;
 
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
 
public class FileSearcher {
    
    public static void main(String[]args) {
        
        String rootPath = new String("E:/folder");
        recursiveSearching(rootPath);
        
    }
    
    /**
     * 파일 재귀 탐색 모듈 <br>
     * @param paramInput
     */
    private static void recursiveSearching(String paramInput){
        File file = new File(paramInput);
        
        if(file.isDirectory()){
            
            /** directory searching **/
            File[] fileList = file.listFiles();
            
            if(fileList == null){
                return;
            }
            
            for(File f : fileList){
                if(f.isHidden()){
                    continue;
                }
                
                String newInPath = f.getAbsolutePath();
                recursiveSearching(newInPath);
            }
        }
        else{
            
            /** process **/
            process(new File(paramInput));
        }
    }
    
    /**
     * 파라미터로 들어온 파일을 읽는 모듈  <br> 
     * @param file
     */
    private static void process(File file) {
        
        String line = null;
        FileInputStream fis = null;
        InputStreamReader isr = null;
        BufferedReader br = null;
        
        try {
            
            fis = new FileInputStream(file);
            isr = new InputStreamReader(fis, "euc-kr");
            br = new BufferedReader(isr);
            
            while((line = br.readLine()) != null) {
                System.out.println(line);
            }
        }
        catch(IOException e) {
            System.err.println(e.getMessage());
            System.exit(1);
        }
    }
}
 
cs


위의 로직을 살펴보면 디렉토리이면 해당 디렉토리의 절대경로를 획득해서 계속해서 탐색해나가고, 파일로 되어있으면 해당 파일을 읽어들이는 프로세스가 구현되어 있다. 그리고 중간에 해당 파일이 숨김으로 표시되어 있다면 아예 탐색을 시도하지 않는다.


위의 로직에 대한 결과 값은 아래와 같다. 아래의 내용은 텍스트 파일에 쓰여진 내용을 그대로 콘솔창으로 출력해본 것이다.


안녕하세요 반갑습니다. 

고구마 텍스트 파일

독수리 텍스트 파일

토마토 텍스트 파일

굿 윌 헌팅

죽은 시인의 사회

콘택트

혐오스런 마츠코의 일생

그리스인 조르바

상실의 시대

참을 수 없는 존재의 가벼움

코스모스

네이버

우아한 형제들

카카오

쿠팡


추가)

코드의 간결함과 if, else 의 구문의 남발때문에 발생하는 들여쓰기의 문제 때문에 항상 본인의 코드가 깔끔한지 혹은 가독성이 좋은지 파악하는 것이 좋다. 따라서 위의 recursiveSearching 메소드를 아래와 같이 수정해볼 수 있다. else 영역을 삭제하고 if 을 통해 들여쓰기 한번만 넣었다.


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
28
/**
 * 파일 재귀 탐색 모듈 <br>
 * @param paramInput
 */
private static void recursiveSearching(String paramInput){
    File file = new File(paramInput);
    
    if(!file.isDirectory()){
        process(file);
        return;
    }
    
    /** directory searching **/
    File[] fileList = file.listFiles();
    
    if(fileList == null){
        return;
    }
    
    for(File f : fileList){
        if(f.isHidden()){
            continue;
        }
        
        String newInPath = f.getAbsolutePath();
        recursiveSearching(newInPath);
    }
}
cs


Posted by doubler
,