Java 디렉토리에서재귀적에서 파일 찾기
Java 그리고, 지정된 디렉토리로부터, 서브 디렉토리도 포함해 재귀적으로 파일을 검색해, 검색 조건에 해당하는 파일 리스트를 취득하는 샘플 프로그램을 소개합니다.
이들은 UNIX 계열 명령의 ls -R , Windows 계열 명령의 dir /s 와 동등한 처리를 실시합니다.
또한 검색 대상 파일 이름에는 와일드 카드 문자로 *를 지정하거나 정규 표현식을 사용하여 검색 할 수 있습니다.
사용법의 예로서, 이하의 경우, 디렉토리 filelist 를 서브 디렉토리를 포함해 재귀적으로 검색해, 확장자 java 의 파일 리스트를 취득합니다.
File[] files = search.listFiles(“C:/filelist/”, “*.java”);
샘플 프로그램
/**
*
*/
public class FileSearch {
public static final int TYPE_FILE_OR_DIR = 1;
public static final int TYPE_FILE = 2;
public static final int TYPE_DIR = 3;
/**
* 지정된 디렉토리 [directoryPath]에서,
* 검색 대상 파일 [fileName]을 재귀 적으로 검색하고 해당
* 파일 객체의 목록을 반환합니다.
*
* 예)
* File[] files =listFiles(“C:/filelist/”, “*.java”);
* 위의 예에서는 디렉토리 filelist를 재귀 적으로 검색하고,
* 확장자 java의 파일 리스트를 취득합니다.
*
* @param directoryPath 검색할 디렉토리를 나타내는 경로
* @param fileName 검색 대상 파일 이름
* 파일명에는 와일드카드 문자로서 *를 지정 가능
* @return 검색과 일치하는 파일 객체
*/
public File[] listFiles(String directoryPath, String fileName) {
// 와일드카드 문자로 *를 정규식으로 변환
if (fileName != null) {
fileName = fileName.replace(“.”, “\\.”);
fileName = fileName.replace(“*”, “.*”);
}
return listFiles (directoryPath, fileName, TYPE_FILE, true, 0);
}
/**
* 지정된 디렉토리 [directoryPath]에서 정규식으로 지정됨
* 검색 대상 파일 [fileNamePattern]을 재귀 적으로 검색하고,
* 해당 파일 객체의 목록을 반환합니다.
*
* 또한, 파일의 갱신일이 지정일수 경과하고 있는지를 검색조건에
* 지정할 수 있습니다.
*
* 예)
* File[] files =
* listFiles(“C:/filelist/”, “*.java”,TYPE_FILE, true, 2);
* 위의 예에서는 디렉토리 filelist를 재귀 적으로 검색하고 7 일 전 이후로 업데이트
* 된 확장자 java의 파일리스트를 취득합니다.
*
* @param directoryPath 검색할 디렉토리를 나타내는 경로
* @param fileNamePattern 검색 대상 파일 이름 [정규 표현식]
* @param type 해당 파일 객체는 [type]에 따라
* 이하의 지정이 가능
* TYPE_FILE_OR_DIR ... 파일 및 디렉토리
* TYPE_FILE ... 파일
* TYPE_DIR ... 디렉토리
* @param isRecursive 재귀 적으로 검색하려면 true
* @param period 검색 대상으로 파일의 갱신 날짜가 지정 일수 경과
* 하고 있는지 여부를 설정 가능
*0의 경우는 대상외
*1 이상인 경우, 지정일수 이후의 파일을 검색 대상으로 한다
* -1 이하의 경우, 지정 일수 이전의 파일을 검색 대상으로 한다
* @return 검색과 일치하는 파일 객체
*/
public File[] listFiles(String directoryPath,
String fileNamePattern, int type,
boolean isRecursive, int period) {
File dir = new File(directoryPath);
if (!dir.isDirectory()) {
throw new IllegalArgumentException
(“인수로 지정된 패스[” + dir.getAbsolutePath() +
"]는 디렉토리가 아닙니다.");
}
File[] files = dir.listFiles();
// 그 출력
for(int i = 0; i < files.length; i++) {
File file = files[i];
addFile (type, fileNamePattern, set, file, period);
// 재귀 적으로 검색 및 디렉토리라면 재귀 적으로 목록에 추가
if (isRecursive && file.isDirectory()) {
listFiles(file.getAbsolutePath(), fileNamePattern,
type, isRecursive, period);
}
}
return (File[]) set.toArray(new File[set.size()]);
}
private void addFile (int type, String match, TreeSet set,
File file, int period) {
switch (type) {
case TYPE_FILE:
if (!file.isFile()) {
return;
}
break;
case TYPE_DIR:
if (!file.isDirectory()) {
return;
}
break;
}
if (match != null && !file.getName().matches(match)) {
return;
}
// 지정일수 경과하고 있는지의 지정이 있는 경우
if (period != 0) {
// 파일 업데이트 날짜
Date lastModifiedDate = new Date(file.lastModified());
String lastModifiedDateStr = new SimpleDateFormat(“yyyyMMdd”)
.format(lastModifiedDate);
// 지정된 날짜 (1 일을 밀리 초로 계산)
long oneDayTime = 24L * 60L * 60L * 1000L;
long periodTime = oneDayTime * Math.abs(period);
Date designatedDate =
new Date(System.currentTimeMillis() – periodTime);
String designatedDateStr = new SimpleDateFormat(“yyyyMMdd”)
.format(designatedDate);
if (period > 0) {
if (lastModifiedDateStr.compareTo(designatedDateStr) < 0) {
return;
}
} else {
if (lastModifiedDateStr.compareTo(designatedDateStr) > 0) {
return;
}
}
}
// 모든 조건에 해당하는 경우 목록에 저장
set.add(file);
}
/** 알파벳순으로 정렬하기 위해 TreeSet을 사용. */
private TreeSet set = new TreeSet();
/**
* 인스턴스를 생성 후, 계속 사용하는 경우는, 이 메소드를
* 호출 클리어할 필요가 있다.
* 예)
* FileSearch search = new FileSearch();
* File[] f1 = search.listFiles(C:/filelist/”, “*.java”);
* search.clear();
* File[] f2 = search.listFiles(“C:/filelist/”, “*.jsp”);
*/
public void clear(){
set.clear();
}
}
실행 결과
샘플 프로그램을 확인하기 위해 filelist 디렉토리를 만들고 다음 파일을 준비했습니다.
파일 이름과 업데이트 날짜가 표시됩니다.
※상, 현재의 일자는2007/08/18라고 합니다.
C:\filelist │ aaa.java 2007/08/18 │ bbb.java 2007/08/18 └─dir ccc.java 17/07/17
◆실행예
System.out.println(“\n●모든 파일 가져오기”);
File[] files = search.listFiles(path, null);
printFileList(files);
search.clear();
System.out.println(“\n● 확장자 java 파일 가져오기”);
files = search.listFiles(path, “*.java”);
printFileList(files);
search.clear();
System.out.println(“\n●모든 파일과 디렉토리 가져오기”);
files = search.listFiles(path, null,search.TYPE_FILE_OR_DIR, true, 0);
printFileList(files);
search.clear();
System.out.println(“\n●현재 날짜부터 2일 전 이후로 업데이트된 파일 가져오기”);
files = search.listFiles(path, null,search.TYPE_FILE, true, 2);
printFileList(files);
search.clear();
System.out.println("\n●현재 날짜에서 30일 이전의 이전 파일 가져오기");
files = search.listFiles(path, null,search.TYPE_FILE, true, -30);
printFileList(files);
search.clear();
}
private static void printFileList(File[] files) {
for(int i = 0; i < files.length; i++) {
File file = files[i];
System.out.println((i + 1) + “: ” + file);
}
}
◆출력 결과
● 모든 파일 가져오기 1: C:\filelist\aaa.java 2: C:\filelist\bbb.java 3: C:\filelist\dir\ccc.java 4: C:\filelist\dir\ddd.java 5: C:\filelist\dir\eee.jpg ●확장자 java의 파일 취득1: C:\filelist\aaa.java 2: C:\filelist\bbb.java 3: C:\filelist\dir\ccc .java 4: C:\filelist\dir\ddd.java ●모든 파일과 디렉토리 가져오기1: C:\filelist\aaa.java 2: C:\filelist\bbb.java 3: C:\filelist\dir 4: C:\filelist\dir\ccc.java 5: C:\filelist\dir\ddd.java 6: C:\filelist\dir\eee.jpg ● 현재 날짜로부터 2일 전 이후로 업데이트된 파일 얻기 1: C:\filelist\aaa.java 2: C:\filelist\bbb.java 3: C:\filelist\dir\ddd.java 4: C:\filelist\dir\eee.jpg ●현재 날짜 에서 30 일 이전의 이전 파일 가져오기 1: C:\filelist\dir\ccc.java