如何按升序对文件名进行排序?

nov*_*eek 20 java sorting file arraylist

我在一个文件夹中有一组文件,所有文件都以类似的名字开头,除了一个.这是一个例子:

Coordinate.txt
Spectrum_1.txt
Spectrum_2.txt
Spectrum_3.txt
.
.
.
Spectrum_11235
Run Code Online (Sandbox Code Playgroud)

我能够列出指定文件夹中的所有文件,但列表不是频谱号的升序.示例:执行程序时,我得到以下结果:

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
Run Code Online (Sandbox Code Playgroud)

但这个顺序不正确.Spectrum_999.txt之后应该有Spectrum_1000.txt文件.有人可以帮忙吗?这是代码:

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

            }   
        }
    }
Run Code Online (Sandbox Code Playgroud)

A4L*_*A4L 30

你要求的是数字排序.您需要实现Comparator并将其传递给Arrays#sort方法.在比较方法中,您需要从每个文件名中提取数字,然后比较数字.

你得到你现在得到的输出的原因是排序发生在字母数字上

这是一个非常基本的方法.此代码使用简单String操作来提取数字.如果您知道文件名的格式(在您的情况下),则此方法有效Spectrum_<number>.txt.更好的提取方法是使用正则表达式.

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());
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

产量

Spectrum_1.txt
Spectrum_2.txt
Spectrum_7.txt
Spectrum_14.txt
Spectrum_999.txt
Spectrum_1000.txt
Spectrum_9990.txt
Spectrum_9991.txt
Run Code Online (Sandbox Code Playgroud)


Div*_*iya 6

NameFileComparatorCommons IO 库中可用的类具有按名称、上次修改日期、大小等对文件数组进行排序的功能。文件可以按升序和降序排序,区分大小写或不区分大小写。

进口 :

org.apache.commons.io.comparator.NameFileComparator

代码 :

File directory = new File(".");
File[] files = directory.listFiles();
Arrays.sort(files, NameFileComparator.NAME_COMPARATOR)
Run Code Online (Sandbox Code Playgroud)

  • 这并没有按照 OP 想要的方式进行排序。它忽略了数字。 (2认同)

Luk*_*der 5

在目前接受的答案做到这一点只对文件的后缀数字是一直叫同一个名字(也就是忽略前缀).

我在这里写博客的更通用的解决方案适用于任何文件名,分段中的名称和以数字方式(如果两个段都是数字)或按字典顺序排序段,否则.想法源于这个答案:

public final class FilenameComparator implements Comparator<String> {
    private static final Pattern NUMBERS = 
        Pattern.compile("(?<=\\D)(?=\\d)|(?<=\\d)(?=\\D)");
    @Override public final int compare(String o1, String o2) {
        // Optional "NULLS LAST" semantics:
        if (o1 == null || o2 == null)
            return o1 == null ? o2 == null ? 0 : -1 : 1;

        // Splitting both input strings by the above patterns
        String[] split1 = NUMBERS.split(o1);
        String[] split2 = NUMBERS.split(o2);
        for (int i = 0; i < Math.min(split1.length, split2.length); i++) {
            char c1 = split1[i].charAt(0);
            char c2 = split2[i].charAt(0);
            int cmp = 0;

            // If both segments start with a digit, sort them numerically using 
            // BigInteger to stay safe
            if (c1 >= '0' && c1 <= '9' && c2 >= '0' && c2 <= '9')
                cmp = new BigInteger(split1[i]).compareTo(new BigInteger(split2[i]));

            // If we haven't sorted numerically before, or if numeric sorting yielded 
            // equality (e.g 007 and 7) then sort lexicographically
            if (cmp == 0)
                cmp = split1[i].compareTo(split2[i]);

            // Abort once some prefix has unequal ordering
            if (cmp != 0)
                return cmp;
        }

        // If we reach this, then both strings have equally ordered prefixes, but 
        // maybe one string is longer than the other (i.e. has more segments)
        return split1.length - split2.length;
    }
}
Run Code Online (Sandbox Code Playgroud)

这也可以处理带有颠覆的版本,例如 version-1.2.3.txt

  • 我看到你在使用正则表达式,我想知道你从哪里得到灵感......我想你应该得到一个 cookie ;-) (2认同)