如何从 java 中的目录顺序读取文件?

how to read files sequentially from a directory in java?

public class File_Reader 
{
public static void main(String[] args) throws FileNotFoundException,IOException
{
    int count_files=0;
    int count_lines=0; 
    ArrayList<String> list_row = new ArrayList<String>();
    File dir = new File("/home/sumit/Desktop/split_20");//folder is loaded
    if(dir.exists())
    {
        int i=0;
        for (File file : dir.listFiles())
        {                                       
            Scanner s = new Scanner(file); 
            System.out.println(file.getAbsoluteFile());
            fl=file.getAbsoluteFile();
            while (s.hasNext())
            {
                list_row.add(s.next());//adding all elements 
                count_lines++;
            }   
            String str[];
            str=new String[count_lines];    
            for(int p=0 ; p<count_lines ; p++)
            {
               str[p]=list_row.get(p);

            }
            count_files++;
            s.close();
        } 
    }
    System.out.println("Count files = "+count_files);
}
}

我的文件按 1.csv、2.csv、3.csv...等排序。 所以我希望我的程序读取这些文件,因为它们出现在 folder.But 程序正在随机读取它们,如 11.csv、8.csv、20.csv...等等。 我的文件夹里有24个文件。

在 Javadoc 中,您会看到无法保证 File.listFiles()

返回文件的顺序

您需要对返回的列表进行排序:请参阅 Collections.sort()

如果 File 的默认排序不符合您的需要,您可以定义自己的 Comparator。

默认排序 File.compareTo() :

Compares two abstract pathnames lexicographically. The ordering defined by this method depends upon the underlying system. On UNIX systems, alphabetic case is significant in comparing pathnames; on Microsoft Windows systems it is not.

您不能直接执行此操作。只需对文件列表进行排序。然后使用该排序列表。

List<File> sortedDirs = Arrays.asList(dir.listFiles());
Collections.sort(sortedDirs, new Comparator<File>() {
    @Override
    public int compare(File f1, File f2) {
        return f1.getName().compareTo(f2.getName());
    }
});

for (File file : sortedDirs){
    ...
}

Collections.sort(List) 将不起作用。因为 File.compareTo() 不保证 return 所有 OS 的值相同。因此,您必须提供自己的 Comparator,如上所示。并且必须使用 Collections.sort(List, Comparator) version

您应该在 for 之前对文件名进行排序,例如类似

的东西
File[] files = dir.listFiles();
List<String> filePaths = new ArrayList<>();
for(File f : files) {
  filePaths.add(f.getName());
}
Collections.sort(files);

for(String fName : files) {
  File sortedFile = new File(fName);
  // and so on

如其他答案中所述,您必须对文件列表进行排序。 Java NIO.2 中有一些方便的函数可以将整个文件读入 List<String> 并遍历文件树。

在我的解决方案中,我使用 TreeMap 对文件路径进行排序并在遍历文件树时读取文件。

此外,您可以通过调用 List::toArray(T[])List<String> 转换为数组。所以你可以这样写:

public static String[] readAllFiles(String path) throws IOException {
    Map<Path, List<String>> readFiles = new TreeMap<>();
    Files.walkFileTree(Paths.get(path), new SimpleFileVisitor<Path>() {
        @Override
        public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
            Objects.requireNonNull(file);
            readFiles.put(file, Files.readAllLines(file, StandardCharsets.UTF_8));
            return FileVisitResult.CONTINUE;
        }
    });
    List<String> lines = new ArrayList<>();
    for (List<String> read : readFiles.values()) {
        lines.addAll(read);
    }
    return lines.toArray(new String[lines.size()]);
}

编辑

如果你的文件名只包含数字那么你可以通过regex/splitting/etc提取数字。文件名。

然后你必须将它添加到 TreeMap

的构造函数中
Map<Path, List<String>> readFiles = new TreeMap<>(new Comparator<Path>() {
    @Override
    public int compare(Path o1, Path o2) {
        Matcher o1Matcher = NUMBER_PATTERN.matcher(o1.getFileName().toString());
        Matcher o2Matcher = NUMBER_PATTERN.matcher(o2.getFileName().toString());
        if (o1Matcher.find() && o2Matcher.find()) {
            return Integer.compare(Integer.parseInt(o1Matcher.group()), Integer.parseInt(o2Matcher.group()));
        } else {
            return o1.compareTo(o2);
        }
    }
});

并在您的 class

中将此模式用作静态字段
private static final Pattern NUMBER_PATTERN = Pattern.compile("(\d+)");