如何从 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+)");
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+)");