Skip to content
Advertisement

How to sort file names in ascending order?

I have a set of files in a folder, and all of them starting with a similar name, except one. Here is an example:

Coordinate.txt
Spectrum_1.txt
Spectrum_2.txt
Spectrum_3.txt
.
.
.
Spectrum_11235

I am able to list all the files from the specified folder, but the list is not in an ascending order of the spectrum number. Example: I get the following result when the program is executed:

Spectrum_999.txt
Spectrum_9990.txt
Spectrum_9991.txt
Spectrum_9992.txt
Spectrum_9993.txt
Spectrum_9994.txt
Spectrum_9995.txt
Spectrum_9996.txt
Spectrum_9997.txt
Spectrum_9998.txt
Spectrum_9999.txt

But this order is not correct. There should be Spectrum_1000.txt file after Spectrum_999.txt. Can anyone help? Here is the code:

import java.io.*;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Scanner;

    public class FileInput {

        public void userInput()
        {
            Scanner scanner = new Scanner( System.in );
            System.out.println("Enter the file path: ");
            String dirPath = scanner.nextLine(); // Takes the directory path as the user input

            File folder = new File(dirPath);
            if(folder.isDirectory())
            {
                File[] fileList = folder.listFiles();

                Arrays.sort(fileList);

                System.out.println("nTotal number of items present in the directory: " + fileList.length );


                // Lists only files since we have applied file filter
                for(File file:fileList)
                {
                    System.out.println(file.getName());
                }

                // Creating a filter to return only files.
                FileFilter fileFilter = new FileFilter()
                {
                    @Override
                    public boolean accept(File file) {
                        return !file.isDirectory();
                    }
                };

                fileList = folder.listFiles(fileFilter);

                // Sort files by name
                Arrays.sort(fileList, new Comparator()
                {
                    @Override
                    public int compare(Object f1, Object f2) {
                        return ((File) f1).getName().compareTo(((File) f2).getName());
                    }
                });

                //Prints the files in file name ascending order
                for(File file:fileList)
                {
                    System.out.println(file.getName());
                }

            }   
        }
    }

Advertisement

Answer

What you are asking for is numerical sort. You need implement a Comparator and pass it to the Arrays#sort method. In the compare method you need to extract the number from each filename an then compare the numbers.

The reason why you get the output you are getting now is that sorting happens alphanumerically

Here a is a very basic way of doing it. This code uses simple String-operation to extract the numbers. This works if you know the format of the filename, in your case Spectrum_<number>.txt. A better way of doing the extraction is to use regular expression.

public class FileNameNumericSort {

    private final static File[] files = {
        new File("Spectrum_1.txt"),
        new File("Spectrum_14.txt"),
        new File("Spectrum_2.txt"),
        new File("Spectrum_7.txt"),     
        new File("Spectrum_1000.txt"), 
        new File("Spectrum_999.txt"), 
        new File("Spectrum_9990.txt"), 
        new File("Spectrum_9991.txt"), 
    };

    @Test
    public void sortByNumber() {
        Arrays.sort(files, new Comparator<File>() {
            @Override
            public int compare(File o1, File o2) {
                int n1 = extractNumber(o1.getName());
                int n2 = extractNumber(o2.getName());
                return n1 - n2;
            }

            private int extractNumber(String name) {
                int i = 0;
                try {
                    int s = name.indexOf('_')+1;
                    int e = name.lastIndexOf('.');
                    String number = name.substring(s, e);
                    i = Integer.parseInt(number);
                } catch(Exception e) {
                    i = 0; // if filename does not match the format
                           // then default to 0
                }
                return i;
            }
        });

        for(File f : files) {
            System.out.println(f.getName());
        }
    }
}

Output

Spectrum_1.txt
Spectrum_2.txt
Spectrum_7.txt
Spectrum_14.txt
Spectrum_999.txt
Spectrum_1000.txt
Spectrum_9990.txt
Spectrum_9991.txt
User contributions licensed under: CC BY-SA
9 People found this is helpful
Advertisement