如何按升序对文件名进行排序?
我在一个文件夹中有一组文件,所有文件都以类似的名字开头,除了一个。 这是一个例子:
Coordinate.txt Spectrum_1.txt Spectrum_2.txt Spectrum_3.txt . . . Spectrum_11235
我能够列出指定文件夹中的所有文件,但列表不是频谱号的升序。 示例:执行程序时,我得到以下结果:
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
但这个顺序不正确。 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()); } } } }
你要求的是数字排序。 您需要实现Comparator并将其传递给Arrays#sort方法。 在比较方法中,您需要从每个文件名中提取数字,然后比较数字。
你得到你现在得到的输出的原因是排序发生在字母数字上
这是一个非常基本的方法。 此代码使用简单的String
-operation来提取数字。 如果您知道文件名的格式(在您的情况下为Spectrum_
。 更好的提取方法是使用正则表达式 。
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() { @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()); } } }
产量
Spectrum_1.txt Spectrum_2.txt Spectrum_7.txt Spectrum_14.txt Spectrum_999.txt Spectrum_1000.txt Spectrum_9990.txt Spectrum_9991.txt
当前接受的答案仅对始终称为相同名称的文件的数字后缀(即忽略前缀)执行此操作。
我在这里写博客的更通用的解决方案适用于任何文件名,分段中的名称和以数字方式(如果两个段都是数字)或按字典顺序排序段。 想法源于这个答案 :
public final class FilenameComparator implements Comparator { 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 (eg 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 (ie has more segments) return split1.length - split2.length; } }
这也可以处理带有颠覆的版本,例如version-1.2.3.txt
Commons IO库中提供的NameFileComparator
类,具有按名称,最后修改日期,大小等排序文件数组的function。文件可以按升序和降序排序,区分大小写或不区分大小写。
import:
org.apache.commons.io.comparator.NameFileComparator
代码:
File directory = new File("."); File[] files = directory.listFiles(); Arrays.sort(files, NameFileComparator.NAME_COMPARATOR)
您可以在上面的评论中找到您的问题的解决方案,但考虑到只发布了链接,我正在从该网站提供代码。 工作得很好。
-
您需要创建自己的AlphanumericalComparator。
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; } }
2.根据此类对文件进行排序。
File[] listOfFiles = rootFolder.listFiles(); Arrays.sort(listOfFiles, new AlphanumFileComparator() ); ...to sth with your files.
希望能帮助到你。 它对我有用,就像一个魅力。
解决方案来自: http : //www.davekoelle.com/files/AlphanumComparator.java
Arrays.sort(fileList, new Comparator() { @Override public int compare(Object f1, Object f2) { String fileName1 = ((File) f1).getName(); String fileName2 = ((File) f1).getName(); int fileId1 = Integer.parseInt(fileName1.split("_")[1]); int fileId2 = Integer.parseInt(fileName2.split("_")[1]); return fileId1 - fileId2; } });
确保处理名称中没有_的文件
只需使用:
-
对于升序:Collections.sort(列表)
-
对于Descending:Collections.sort(List,Collections.reverseOrder())
你可以使用Collections.sort(fileList);
排序arraylist。
然后用
for(File file:fileList) System.out.println(file.getName());
Collections.sort()
只是另一种方式,但使用java8的力量
List x = Files.list(Paths.get("C:\\myPath\\Tools")) .filter(p -> Files.exists(p)) .map(s -> s.getFileName()) .sorted() .collect(Collectors.toList()); x.forEach(System.out::println);