0

I want to create a map for a Path.

That path contains different folders and each folder has some files.

Let's say, path: c:/project

The project has 2 folders A and B. A has 2 text file- 1.txt, 2.txt and B has 3.txt file The output should be [A= {1.txt,2.txt}, B= {3.txt}]

I am using java8 Currently, I am doing

    try (Stream<Path> files = Files.list(getOutputDirectory()))
    {
        Map<String, String> fileList = files.map(input -> input.toFile().getName())
                .collect(Collectors.toMap(key -> key, value -> value));

        logger.info("testing " + fileList);

    }
    catch (final IOException exception)
    {
       exception.printStackTrace();
    }

but output is {A=A,B=B}; expected is [A= {1.txt,2.txt}, B= {3.txt}]

Naman
  • 27,789
  • 26
  • 218
  • 353
Rhea
  • 381
  • 1
  • 7
  • 22

3 Answers3

1

Try this one:

Map<String, List<String>> fileList = files.flatMap(path -> {
    try {
        return Files.list(path);
    } catch (IOException e) {
        e.printStackTrace();
    }
    return files;
}).collect(Collectors.groupingBy(path -> path.getParent().getFileName().toString(),
        Collectors.mapping(path -> path.getFileName().toString(), Collectors.toList())));

, output

{A=[1.txt, 2.txt], B=[3.txt]}
Naman
  • 27,789
  • 26
  • 218
  • 353
0xh3xa
  • 4,801
  • 2
  • 14
  • 28
1

I don't know what is your full code, but you could try this :

Path getOutputDirectory = Paths.get("c:/project");
getOutputDirectory.toFile().getName();

try(Stream<Path> files = Files.list(getOutputDirectory)) {
     Map<String, String<Path>> fileList = 
                               files.collect(Collectors.groupingBy(p -> p.toFile().isDirectory()));
     System.out.println(fileList); 
} cath (IOException e) {
      System.out.print(e.getMessage()); }
Eduard A
  • 370
  • 3
  • 9
-1

Here an example with /Users/Fabien/project that has 2 folders A and B. A has 2 text file- 1.txt, 2.txt and B has 3.txt file :

  public static void main(String[] args) throws IOException {
        Path projectPath = Paths.get("/Users/Fabien/project/");
        Set<Path> directoriesToList = Files.list(projectPath).map(Path::getFileName).collect(Collectors.toSet());
        Map<String, List<String>> fileList = Files.walk(projectPath).filter(p -> {
            try {
                return directoriesToList.contains(p.getParent().getFileName());
            } catch (Exception e) {
                return false;
            }
        }).collect(Collectors.groupingBy(p -> p.getParent().getFileName().toString()))
                .entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, file -> file.getValue().stream().map(Path::getFileName).map(Path::toString).collect(Collectors.toList())));

        System.out.println("testing " + fileList);
    }
Fabien
  • 974
  • 9
  • 14
  • Great answer. But please teach the new java coders better manners, ditch the catch block, and add 'throws IOException' to main's signature. 'print the stack trace and continue execution' is a silly default, and us pros parroting it in e.g. SO answers is perpetuating the silliness. If that just doesn't fit your sensibilities, at least make that 'throw new RuntimeException("uncaught", exception); instead. – rzwitserloot Jul 09 '20 at 23:00
  • Checked exceptions like IOException was designed to force developers to handle the exception if he can make a decision with it or rethrows it otherwise. There is nothing silly about 'print the stack trace and continue execution', it's all about what your business rules are – Fabien Jul 09 '20 at 23:21