List files from a directory in Java

1

I have this code with which I am listing the .sql files in a directory, specifically 20 files whose name is their number. When the program lists the files it does it in the following way (below code). How can I do it in ascending order and not like that?

public class Principal {

public static void main(String[] args) {

    Scanner sc = new Scanner(System.in);
    System.out.println("Escribe la ruta: ");
    String ruta = sc.nextLine();
    System.out.println("Escribe la extension: ");
    String ext = sc.nextLine();
    File carpeta = new File(ruta);
    File[] archivos;
    if(carpeta.exists()) {
        if(carpeta.isDirectory()) {
            archivos = carpeta.listFiles();
            for(int i=0; i<archivos.length; i++) {
                if(archivos[i].getName().endsWith(ext)) 
                    System.out.println(archivos[i].getName());
            }
        }
    }

Escribe la ruta: 
C:\Users\SAG\Desktop\Sql\CarpetaSQL
Escribe la extension: 
sql
1.sql
10.sql
11.sql
12.sql
13.sql
14.sql
15.sql
16.sql
17.sql
18.sql
19.sql
2.sql
20.sql
3.sql
4.sql
5.sql
6.sql
7.sql
8.sql
9.sql
    
asked by Sergio AG 30.05.2018 в 02:52
source

2 answers

0

what you have to do is pass to the sort () method of the Array a custom comparator. in this case AlphanumFileComparator and that way your code should be as follows:

import org.apache.commons.io.filefilter.WildcardFileFilter;

import java.io.File;
import java.io.FileFilter;
import java.util.Arrays;
import java.util.Scanner;

public class Principal {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        System.out.println("Escribe la ruta: ");
        String ruta = sc.nextLine();
        System.out.println("Escribe la extension: ");
        String ext = sc.nextLine();
        File carpeta = new File(ruta);
        FileFilter fileFilter = new WildcardFileFilter("*." + ext);
        if (carpeta.exists()) {
            if (carpeta.isDirectory()) {
                File[] archivos = carpeta.listFiles(fileFilter);
                Arrays.sort(archivos, new AlphanumFileComparator());
                for (int i = 0; i < archivos.length; i++) {
                    System.out.println(archivos[i].getName());

                }
            }
        }
    }
}

This is the Comparator code:

import java.io.File;
import java.util.Comparator;

public class AlphanumFileComparator implements Comparator {

    private final boolean isDigit(char ch) {
        return ch >= 48 && ch <= 57;
    }


    private final String getChunk(String s, int slength, int marker) {
        StringBuilder chunk = new StringBuilder();
        char c = s.charAt(marker);
        chunk.append(c);
        marker++;
        if (isDigit(c)) {
            while (marker < slength) {
                c = s.charAt(marker);
                if (!isDigit(c))
                    break;
                chunk.append(c);
                marker++;
            }
        } else {
            while (marker < slength) {
                c = s.charAt(marker);
                if (isDigit(c))
                    break;
                chunk.append(c);
                marker++;
            }
        }
        return chunk.toString();
    }

    public int compare(Object o1, Object o2) {
        if (!(o1 instanceof File) || !(o2 instanceof File)) {
            return 0;
        }
        File f1 = (File) o1;
        File f2 = (File) o2;
        String s1 = f1.getName();
        String s2 = f2.getName();

        int thisMarker = 0;
        int thatMarker = 0;
        int s1Length = s1.length();
        int s2Length = s2.length();

        while (thisMarker < s1Length && thatMarker < s2Length) {
            String thisChunk = getChunk(s1, s1Length, thisMarker);
            thisMarker += thisChunk.length();

            String thatChunk = getChunk(s2, s2Length, thatMarker);
            thatMarker += thatChunk.length();

            /** If both chunks contain numeric characters, sort them numerically **/

            int result = 0;
            if (isDigit(thisChunk.charAt(0)) && isDigit(thatChunk.charAt(0))) {
                // Simple chunk comparison by length.
                int thisChunkLength = thisChunk.length();
                result = thisChunkLength - thatChunk.length();
                // If equal, the first different number counts
                if (result == 0) {
                    for (int i = 0; i < thisChunkLength; i++) {
                        result = thisChunk.charAt(i) - thatChunk.charAt(i);
                        if (result != 0) {
                            return result;
                        }
                    }
                }
            } else {
                result = thisChunk.compareTo(thatChunk);
            }

            if (result != 0)
                return result;
        }
        return s1Length - s2Length;
    }
}

That way your result will be something like:

Escribe la ruta: 
/home/efren/Archivos
Escribe la extension: 
sql
1.sql
2.sql
3.sql
4.sql
5.sql
6.sql
7.sql
8.sql
9.sql
10.sql
11.sql
12.sql
13.sql

Process finished with exit code 0
    
answered by 30.05.2018 в 05:46
0

This question is a bit Old but I would like to exemplify another way Using Modern Classes (from java 8+ and lambda) using the package java.nio.file and listing files by using DirectoryStream

NOTE:

This solution tries to be as simple as possible. and only "order the files that your name is numbers" if the name of this are not numbers will be listed at the end of the list Ordered by "Natural Ordering". To apply a more "refined" order you must create a java.util.Comparator and use files.sort(<El Comparator creado>) as defined in the other answer.

import java.io.IOException;
import java.nio.file.DirectoryStream;
import java.nio.file.Files;
import java.nio.file.LinkOption;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Scanner;


public class orderFileList {

    /**
     * @param args the command line arguments
     * @throws java.io.IOException
     */
    public static void main(String[] args) throws IOException {
        Scanner sc = new Scanner(System.in);
        System.out.println("Escribe la ruta: ");
        String ruta = sc.nextLine();
        System.out.println("Escribe la extension: ");
        String ext = sc.nextLine();
        Path dir = Paths.get(ruta);
        if (Files.exists(dir, LinkOption.NOFOLLOW_LINKS) && Files.isDirectory(dir, LinkOption.NOFOLLOW_LINKS)) {
            try (DirectoryStream<Path> stream = Files.newDirectoryStream(dir, String.format("*.%s", ext))) {
                ArrayList<Path> files = new ArrayList<>();
                stream.forEach(files::add);
                //utilize un natural order primero para ordenar por nombre
                files.sort(Comparator.naturalOrder());
                //utilize nuestro ordernado por Numero.
                files.sort(Comparator.comparing(file -> getnumeric(file),Comparator.nullsLast(Comparator.naturalOrder())));
                files.forEach( file -> System.out.println(file.getFileName().toString()));
            }
        }
    }

    private static Integer getnumeric(Path file) {
        try {
            return Integer.parseInt(file.getFileName().toString().substring(0, file.getFileName().toString().indexOf('.')));
        } catch (NumberFormatException e) {
            return null;
        }
    }

result of an example:

Escribe la ruta: 
C:\Users\silencio\Desktop\test
Escribe la extension: 
sql
1.sql
2.sql
3.sql
4.sql
5.sql
6.sql
7.sql
8.sql
9.sql
10.sql
11.sql
12.sql
13.sql
14.sql
15.sql
16.sql
17.sql
18.sql
19.sql
20.sql
ad.sql
ed.sql
    
answered by 23.12.2018 в 10:30