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

1.7k Views Asked by At

Given a File dir I need to find the highest numeric file name(if any exist)

My approach:

// 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;
}

Considering the file count in the folder can get quite large(300k+) my concern is performance related.

Is this at all an acceptable solution? And is there a better way?

3

There are 3 best solutions below

7
Fred Porciúncula On BEST ANSWER

You can use Java 7 NIO's DirectoryStream to go through your files using a filter to make sure you ignore the files that are not relevant to you.

Here is the filter:

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

}

And here is the code using it:

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

This will only go through files with completely numeric names (without or with any extension).


Just for the record, here is a slightly simpler way to do the same with 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
    }
}
3
Uma Kanth On

I would suggest you to sort the files and take the first entry or the last entry.

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

For very large amounts of numbers, the best way to sort them is with a Heap Sort. For example

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

HeapSort

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

An example implementation of this would be.

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