0

I have a location where 3000 files is stored. But i want to get the list of 1000 files at a time and in next call another 1000 files and so on.

Please find my below code :

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class FileSystem {

    public static void main(String args[]) throws Exception {
        FileSystem.createListFile();
        FileSystem.getFileInBatch();
    }

    private static void getFileInBatch() {
        int MAX_INDEX = 1000;
        List<String> result = new ArrayList<>();

        try (Stream<Path> walk = Files.walk(Paths.get("C://FileTest"))) {

            List<String> batchResult = walk.filter(p -> Files.isRegularFile(p) && p.getFileName().toString().endsWith(".txt"))
                    .sorted(Comparator.comparingInt(FileSystem::pathToInt))
                    .map(x -> x.toString()).limit(MAX_INDEX).collect(Collectors.toList());

            batchResult.forEach(System.out::println);
            System.out.println(batchResult.size());
            result.addAll(batchResult);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }



    private static int pathToInt(final Path path) {
        return Integer.parseInt(path.getFileName()
                .toString()
                .replaceAll("Aamir(\\d+).txt", "$1")
        );
    }

    private static void createListFile() throws IOException {
        for (int i = 0; i < 3000; i++) {
            File file = new File("C://FileTest/Aamir" + i + ".txt");

            if (file.createNewFile()) {

                System.out.println(file.getName() + " is created!");
            }
        }
    }

}

I am able to get the first 1000 (Aamir0.txt to Aamir999.txt) files using the limit in streams.

Now how can i get the next 1000 files ( Aamir1000.txt to Aamir1999.txt) in batches and then the next 1000 files. Im expecting some loops who will continuously give 1000 ordered files in batches.

Harshal Parekh
  • 5,918
  • 4
  • 21
  • 43
codehunter
  • 81
  • 2
  • 14
  • 1
    Please, take a look onto https://stackoverflow.com/questions/30641383/java-8-stream-with-batch-processing it's may help – RoninDev May 07 '20 at 08:03
  • Will it always be 3000 files? – cegredev May 07 '20 at 08:34
  • No, it will be a huge number of files. i was trying for first do it 3000 files so we can do it same – codehunter May 07 '20 at 08:40
  • @AAMIRAZAM Okay. Also, what exactly are you putting into the list? The path to all the files? I'm having a hard time understanding your code. – cegredev May 07 '20 at 08:43
  • @Schred: There is a location where huge number of files are stored let say 4000 files. Now I want to get the pick 1000 files at a time in a batch and do some operation and then pick up the next 1000 files and do some operation and next pick the next 1000 files and do the operation. This will continue until I won't visit all the files in the location. – codehunter May 07 '20 at 12:35
  • @ Schred: In the list, it gets the filename of the 1000 files – codehunter May 07 '20 at 12:36

2 Answers2

1

I'm not sure what you want to do with each file, but this logic should work for you:

private static final int MAX_VALUE = 5;

public static void main(String[] args) {
    try (Stream<Path> walk = Files.walk(Paths.get("path/to/your/directory"))) {

        List<String> list = new ArrayList<>(MAX_VALUE);
        walk.filter(path -> path.getFileName().toString().endsWith("txt"))
            .sorted((a, b) -> compare(a, b)
            .forEach(path -> handlePath(path, list));

    } catch (IOException e) {
        e.printStackTrace();
    }
}

public static void handlePath(Path path, List<String> list) {
    list.add(path.toString());

    if (list.size() >= MAX_VALUE) {
        // Do something

        list.clear();
    }
}

public static int compare(Path a, Path b) {
    String aStr = a.getFileName().toString(), bStr = b.getFileName().toString();

    int valA = Integer.parseInt(aStr.replaceAll("[^0-9.]|\\.", ""));
    int valB = Integer.parseInt(bStr.replaceAll("[^0-9.]|\\.", ""));

    return valA - valB;
}
cegredev
  • 1,485
  • 2
  • 11
  • 25
0

You are using streams and they have fine APIs to do your desire.

you are limiting the reading data with

.limit(MAX_INDEX)

for getting other results one way is to use combination of skip and limit methods:

.skip(MAX_INDEX).limit(MAX_INDEX)

this way you can access the second 1000 characters based on your MAX_INDEX value.

Majid Roustaei
  • 1,556
  • 1
  • 20
  • 39