从目录中获取最大的数字文件名(作为 int)- Java

Get the highest numeric file name(as int) from directory - Java

给定一个 File dir 我需要找到最大的数字文件名(如果存在的话)

我的做法:

// get the highest numeric file name(as int) from given directory
public static final int getHighestNumericFileName(File dir) {
    int result = -1;

    for (File f : dir.listFiles()) {
        String name = f.getName();
        name = name.substring(0, name.indexOf('.'));
        if (StringUtils.isNumeric(name)) {
            int val = Integer.parseInt(name);
            if (val > result)
                result = val;
        }
    }

    return result;
}

考虑到文件夹中的文件数可能会变得非常大 (300k+),我担心的是性能问题。

这是一个可以接受的解决方案吗?还有更好的方法吗?

我建议您对文件进行排序,取第一个条目或最后一个条目。

FileFilter fileFilter = new WildcardFileFilter("\d+.txt");
File[] files = dir.listFiles(fileFilter);
Arrays.sort(files);//sorts lexicographically

对于数量非常大的数字,最好的排序方式是使用 Heap Sort。例如

int[] yourFiles = {} //Puts all file names in array
HeapSort.sort(yourFiles);
result = yourFiles[yourFilens.length-1];

堆排序

public class HeapSort 
{
    private static int[] a;
    private static int n;
    private static int left;
    private static int right;
    private static int largest;


    public static void buildheap(int []a)
    {
        n=a.length-1;
        for(int i=n/2;i>=0;i--)
        {
            maxheap(a,i);
        }
    }

    public static void maxheap(int[] a, int i)
    { 
        left=2*i;
        right=2*i+1;
        if(left <= n && a[left] > a[i])
        {
            largest=left;
        }
        else
        {
            largest=i;
        }

        if(right <= n && a[right] > a[largest])
        {
            largest=right;
        }

        if(largest!=i)
        {
            exchange(i,largest);
            maxheap(a, largest);
        }
    }

    public static void exchange(int i, int j)
    {
        int t=a[i];
        a[i]=a[j];
        a[j]=t; 
    }

    public static void sort(int[] a0)
    {
        a=a0;
        buildheap(a);

        for(int i=n;i>0;i--)
        {
            exchange(0, i);
            n=n-1;
            maxheap(a, 0);
        }
    }
}

一个示例实现是。

import java.util.Arrays;
public class Test
{
    public static void main(String[] args)
    {
        int[] test = {1,5,6,8,6,41};
        HeapSort.sort(test);
        System.out.println(Arrays.toString(test));
    }
}

您可以使用 Java 7 NIO 的 DirectoryStream 使用过滤器浏览您的文件,以确保您忽略与您无关的文件。

这是过滤器:

class NumericFilter implements DirectoryStream.Filter<Path> {

    private static final Pattern PATTERN = Pattern.compile("\d+|\d+\..*");

    @Override
    public boolean accept(Path entry) throws IOException {
        return PATTERN.matcher(entry.getFileName().toString()).matches();
    }

}

下面是使用它的代码:

try (DirectoryStream<Path> stream = Files.newDirectoryStream(Paths.get(dir), new NumericFilter())) {
    for (Path path : stream) {
        // do what you want
    }
}

这只会遍历具有完整数字名称(不带或带任何扩展名)的文件。


仅作记录,这里有一个稍微简单的方法来对 Java 8 做同样的事情:

final Pattern pattern = Pattern.compile("\d+\..*");
try (DirectoryStream<Path> stream = Files.newDirectoryStream(Paths.get(dir),
        entry -> pattern.matcher(entry.getFileName().toString()).matches())) {
    for (Path path : stream) {
        // do what you want
    }
}