수정 된 날짜별로 정렬 된 Java에서 파일을 나열하는 가장 좋은 방법은?

StackOverflow https://stackoverflow.com/questions/203030

  •  03-07-2019
  •  | 
  •  

문제

디렉토리에 파일 목록을 가져오고 싶지만 가장 오래된 파일이 가장 먼저 정렬하고 싶습니다. 내 해결책은 file.listfiles를 호출하고 File.LastModified를 기반으로 목록을 리조트하는 것이지만 더 나은 방법이 있는지 궁금했습니다.

편집 : 제안 된 바와 같이 현재 솔루션은 익명 비교기를 사용하는 것입니다.

File[] files = directory.listFiles();

Arrays.sort(files, new Comparator<File>(){
    public int compare(File f1, File f2)
    {
        return Long.valueOf(f1.lastModified()).compareTo(f2.lastModified());
    } });
도움이 되었습니까?

해결책

귀하의 솔루션이 유일한 현명한 방법이라고 생각합니다. 파일 목록을 얻는 유일한 방법은 사용하는 것입니다. file.listfiles () 그리고 문서는 이것이 반환 된 파일의 순서에 대해 보장하지 않는다고 명시하고 있습니다. 그러므로 당신은 a를 써야합니다 비교기 그것은 사용합니다 file.lastModified () 파일 배열과 함께 이것을 전달합니다. Array.Sort ().

다른 팁

파일이 많으면 더 빠를 수 있습니다. 이것은 각 파일의 마지막으로 수정 된 날짜가 가져 오도록 장식 스토어-결합 패턴을 사용합니다. 한 번 정렬 알고리즘이 두 파일을 비교할 때마다마다가 아니라. 이것은 잠재적으로 I/O 호출 수를 O (n log n)에서 o (n)으로 줄입니다.

그러나 더 많은 코드이므로 주로 속도에 관심이있는 경우에만 사용해야하며 실제로는 측정 할 수 있습니다 (확인하지 않은).

class Pair implements Comparable {
    public long t;
    public File f;

    public Pair(File file) {
        f = file;
        t = file.lastModified();
    }

    public int compareTo(Object o) {
        long u = ((Pair) o).t;
        return t < u ? -1 : t == u ? 0 : 1;
    }
};

// Obtain the array of (file, timestamp) pairs.
File[] files = directory.listFiles();
Pair[] pairs = new Pair[files.length];
for (int i = 0; i < files.length; i++)
    pairs[i] = new Pair(files[i]);

// Sort them by timestamp.
Arrays.sort(pairs);

// Take the sorted pairs and extract only the file part, discarding the timestamp.
for (int i = 0; i < files.length; i++)
    files[i] = pairs[i].f;

비슷한 접근 방식은 무엇이지만 긴 물체로의 권투가 없음 :

File[] files = directory.listFiles();

Arrays.sort(files, new Comparator<File>() {
    public int compare(File f1, File f2) {
        return Long.compare(f1.lastModified(), f2.lastModified());
    }
});

Java 8 이후의 우아한 솔루션 :

File[] files = directory.listFiles();
Arrays.sort(files, Comparator.comparingLong(File::lastModified));

또는 내림차순으로 원한다면 반전하십시오.

File[] files = directory.listFiles();
Arrays.sort(files, Comparator.comparingLong(File::lastModified).reversed());

당신은 또한 볼 수 있습니다 아파치 커먼즈 IO, 그것은 내장되어 있습니다 마지막 수정 된 비교기 파일 작업을위한 다른 많은 유틸리티.

Java 8 :

Arrays.sort(files, (a, b) -> Long.compare(a.lastModified(), b.lastModified()));

수입 :

org.apache.commons.io.comparator.LastModifiedFileComparator

아파치 커먼즈

코드 :

public static void main(String[] args) throws IOException {
        File directory = new File(".");
        // get just files, not directories
        File[] files = directory.listFiles((FileFilter) FileFileFilter.FILE);

        System.out.println("Default order");
        displayFiles(files);

        Arrays.sort(files, LastModifiedFileComparator.LASTMODIFIED_COMPARATOR);
        System.out.println("\nLast Modified Ascending Order (LASTMODIFIED_COMPARATOR)");
        displayFiles(files);

        Arrays.sort(files, LastModifiedFileComparator.LASTMODIFIED_REVERSE);
        System.out.println("\nLast Modified Descending Order (LASTMODIFIED_REVERSE)");
        displayFiles(files);

    }

정렬중인 파일을 동시에 수정하거나 업데이트 할 수있는 경우 정렬을 수행하는 것입니다.


Java 8+

private static List<Path> listFilesOldestFirst(final String directoryPath) throws IOException {
    try (final Stream<Path> fileStream = Files.list(Paths.get(directoryPath))) {
        return fileStream
            .map(Path::toFile)
            .collect(Collectors.toMap(Function.identity(), File::lastModified))
            .entrySet()
            .stream()
            .sorted(Map.Entry.comparingByValue())
//            .sorted(Collections.reverseOrder(Map.Entry.comparingByValue()))  // replace the previous line with this line if you would prefer files listed newest first
            .map(Map.Entry::getKey)
            .map(File::toPath)  // remove this line if you would rather work with a List<File> instead of List<Path>
            .collect(Collectors.toList());
    }
}

Java 7

private static List<File> listFilesOldestFirst(final String directoryPath) throws IOException {
    final List<File> files = Arrays.asList(new File(directoryPath).listFiles());
    final Map<File, Long> constantLastModifiedTimes = new HashMap<File,Long>();
    for (final File f : files) {
        constantLastModifiedTimes.put(f, f.lastModified());
    }
    Collections.sort(files, new Comparator<File>() {
        @Override
        public int compare(final File f1, final File f2) {
            return constantLastModifiedTimes.get(f1).compareTo(constantLastModifiedTimes.get(f2));
        }
    });
    return files;
}


이 두 솔루션 모두 임시 맵 데이터 구조를 생성하여 디렉토리의 각 파일에 대해 일정한 마지막 수정 시간을 절약합니다. 우리 가이 작업을 수행 해야하는 이유는 정렬을 수행하는 동안 파일이 업데이트되거나 수정되면 비교 중 마지막 수정 시간이 비교 중에 변경 될 수 있기 때문에 비교기가 비교기 인터페이스의 일반 계약의 전환 요구 사항을 위반하기 때문입니다.

반면에, 파일이 귀하의 정렬 중에 업데이트되거나 수정되지 않는다는 것을 알고 있다면이 질문에 제출 된 다른 답변을 거의 얻을 수 있습니다.

public String[] getDirectoryList(String path) {
    String[] dirListing = null;
    File dir = new File(path);
    dirListing = dir.list();

    Arrays.sort(dirListing, 0, dirListing.length);
    return dirListing;
}

구아바를 시도 할 수 있습니다 주문:

Function<File, Long> getLastModified = new Function<File, Long>() {
    public Long apply(File file) {
        return file.lastModified();
    }
};

List<File> orderedFiles = Ordering.natural().onResultOf(getLastModified).
                          sortedCopy(files);

Apache를 사용할 수 있습니다 LastModifiedFileComParator 도서관

 import org.apache.commons.io.comparator.LastModifiedFileComparator;  


File[] files = directory.listFiles();
        Arrays.sort(files, LastModifiedFileComparator.LASTMODIFIED_COMPARATOR);
        for (File file : files) {
            Date lastMod = new Date(file.lastModified());
            System.out.println("File: " + file.getName() + ", Date: " + lastMod + "");
        }
private static List<File> sortByLastModified(String dirPath) {
    List<File> files = listFilesRec(dirPath);
    Collections.sort(files, new Comparator<File>() {
        public int compare(File o1, File o2) {
            return Long.compare(o1.lastModified(), o2.lastModified());
        }
    });
    return files;
}
Collections.sort(listFiles, new Comparator<File>() {
        public int compare(File f1, File f2) {
            return Long.compare(f1.lastModified(), f2.lastModified());
        }
    });

어디 listFiles ArrayList의 모든 파일 모음입니다

같은 문제를 검색 할 때이 게시물에 왔지만 android. 나는 이것이 마지막 수정 날짜로 정렬 된 파일을 얻는 가장 좋은 방법이라고 말하지는 않지만 아직 내가 찾은 가장 쉬운 방법입니다.

아래 코드는 누군가에게 도움이 될 수 있습니다.

File downloadDir = new File("mypath");    
File[] list = downloadDir.listFiles();
    for (int i = list.length-1; i >=0 ; i--) {
        //use list.getName to get the name of the file
    }

감사

추가 비교기없이 문제를 처리하는 매우 쉽고 편리한 방법이 있습니다. 수정 된 날짜를 파일 이름으로 문자열로 코딩하고 정렬 한 다음 나중에 다시 제거하십시오.

고정 길이 20의 문자열을 사용하여 수정 된 날짜 (긴)를 넣고 주요 0을 채우십시오. 그런 다음 파일 이름을이 문자열에 추가하십시오.

String modified_20_digits = ("00000000000000000000".concat(Long.toString(temp.lastModified()))).substring(Long.toString(temp.lastModified()).length()); 

result_filenames.add(modified_20_digits+temp.getAbsoluteFile().toString());

이런 일은 여기에 있습니다 :

filename1 : c : data file1.html 마지막 수정 : 1532914451455 마지막 수정 된 20 자리 : 00000001532914451455

filename1 : c : data file2.html 마지막 수정 : 1532918086822 마지막 수정 된 20 자리 : 00000001532918086822

파일 이름을 다음으로 변환합니다.

filename1 : 00000001532914451455c : data file1.html

filename2 : 00000001532918086822c : data file2.html

그런 다음이 목록을 정렬 할 수 있습니다.

나중에 20자를 다시 제거하는 것만으로는 (Java 8에서. replaceall 함수를 사용하여 한 줄만 한 줄로 전체 배열에 대해 스트라이프 할 수 있습니다).

우리는 많은 숫자를 다루지 않기 때문에 훨씬 더 쉬울 수있는 완전히 다른 방법이 있습니다.

모든 파일 이름과 마지막으로 변형 된 날짜를 검색 한 후 전체 배열을 정렬하는 대신 목록의 올바른 위치에서 검색 한 직후에 모든 파일 이름을 삽입 할 수 있습니다.

당신은 다음과 같이 할 수 있습니다 :

list.add(1, object1)
list.add(2, object3)
list.add(2, object2)

객체 2를 위치 2에 추가하면 Object 3을 위치 3으로 이동합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top