Programing

날짜를 수정하여 Java로 파일을 나열하는 가장 좋은 방법은 무엇입니까?

lottogame 2020. 4. 14. 08:24
반응형

날짜를 수정하여 Java로 파일을 나열하는 가장 좋은 방법은 무엇입니까?


디렉토리에 파일 목록을 가져오고 싶지만 가장 오래된 파일이 먼저 정렬되도록 정렬하고 싶습니다. 내 솔루션은 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 () 를 사용 하는 것이며 문서는 반환 된 파일의 순서를 보증하지 않습니다. 따라서 File.lastModified () 를 사용 하는 Comparator 를 작성하고 이를 파일 배열과 함께 Arrays.sort ()에 전달해야 합니다.


파일이 많은 경우 더 빠를 수 있습니다. 이것은 sortate-sort-undecorate 패턴을 사용하므로 정렬 알고리즘이 두 파일을 비교할 때마다가 아니라 각 파일의 마지막 수정 날짜를 한 번만 가져옵니다 . 이는 잠재적으로 O (n log n)에서 O (n)으로의 I / O 호출 수를 줄입니다.

그러나 더 많은 코드이므로 속도에 주로 관심이 있고 실제로 확인하지 않은 것보다 실제로 더 빠를 경우에만 사용해야합니다.

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;

비슷한 접근 방식에 관한 것이지만 Long 객체에는 권투가 없습니다.

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());

또한 apache commons IO 를 볼 수 있으며, 마지막으로 수정 된 비교기 와 파일 작업을위한 많은 다른 유용한 유틸리티가 있습니다.


자바 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);

    }

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


자바 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());
    }
}

자바 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());
        }
    });

listFilesArrayList의 모든 파일 모음은 어디에 있습니까?


나는 같은 문제를 찾고 있었지만이 게시물에 왔습니다 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());

여기서 일어나는 일은 :

파일 이름 1 : C : \ data \ file1.html 마지막 수정 : 1532914451455 마지막 수정 20 자리 : 00000001532914451455

파일 이름 1 : C : \ data \ file2.html 마지막 수정 : 1532918086822 마지막 수정 20 자리 : 00000001532918086822

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

파일 이름 1 : 00000001532914451455C : \ data \ file1.html

파일 이름 2 : 00000001532918086822C : \ data \ file2.html

그런 다음이 목록을 정렬하면됩니다.

Java 문자 8에서는 .replaceAll 함수를 사용하여 한 줄만으로 전체 Array에 대해 20자를 제거 할 수 있습니다.


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

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

다음과 같이 할 수 있습니다.

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

object2를 위치 2에 추가하면 object3이 위치 3으로 이동합니다.

참고 URL : https://stackoverflow.com/questions/203030/best-way-to-list-files-in-java-sorted-by-date-modified

반응형