Sumit Dharma
Sumit Dharma

Reputation: 1

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

My files are sorted like 1.csv,2.csv,3.csv....so on. so I want my program to read these files as they appear in folder.But program is reading them randomly like 11.csv,8.csv,20.csv...so on. I have 24 files inside the folder.

Upvotes: 0

Views: 3086

Answers (4)

Flown
Flown

Reputation: 11740

As mentioned in the other answers you have to sort your list of files. There are some convenient functions in Java NIO.2 to read whole files into List<String> and walk the file tree.

In my solution I used a TreeMap to sort the file paths and read the files while walking the file tree.

Further you can convert a List<String> to an array by invoking List::toArray(T[]). So you can write:

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

EDIT

If your filenames only containing numbers then you can extract the numbers by regex/splitting/etc. the filename.

Then you have to add this to the constructor of the 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);
        }
    }
});

And use this Pattern as static field in your class

private static final Pattern NUMBER_PATTERN = Pattern.compile("(\\d+)");

Upvotes: 0

afzalex
afzalex

Reputation: 8652

You cannot do this directly. Just sort the list of files. And then use that sorted list.

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) will not work. Because File.compareTo() doesn't guarantee to return same value on all OS. So you will have to provide your own Comparator as I shown above. And will have to use Collections.sort(List, Comparator) version

Upvotes: 0

Beno&#238;t
Beno&#238;t

Reputation: 1100

In the Javadoc, you'll see that there is no guarantee on the order in which files are returned by File.listFiles()

You'll need to sort the returned list: See Collections.sort()

If the default ordering of File does not suit your need, you could define your own Comparator.

Default ordering by 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.

Upvotes: 2

francesco foresti
francesco foresti

Reputation: 2043

you should sort the filenames prior to the for, e.g. something along the lines of

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

Upvotes: 0

Related Questions