2

I am trying to understand the Java 8 Stream-feature.

I would like to catch all files in an array (could als be list) in all subdirectories of a specific directory path.

My code throws an java.lang.ArrayStoreException Error

  File[] files = Files.walk(Paths.get(path))
      .filter(Files::isRegularFile)
      .toArray(File[]::new);

Another thing I tried is just add the file names to an existing ArrayList:

  ArrayList<String> existingNames = new ArrayList<String>();
  Files.walk(Paths.get(path))
      .filter(Files::isRegularFile)
      .forEach(p -> existingNames.add(p.getFileName()));

This throws a java.lang.ArrayStoreException Error as well.

Something else I tried with the same result was:

  File[] files = Files.walk(Paths.get(path))
      .filter(Files::isRegularFile)
      .toArray(File[]::new);

Can anyone point me in the right direction?

The full stack trace is:

Exception in thread "main" java.lang.ArrayStoreException at java.lang.System.arraycopy(Native Method) at java.util.stream.SpinedBuffer.copyInto(SpinedBuffer.java:198) at java.util.stream.Nodes$SpinedNodeBuilder.copyInto(Nodes.java:1290) at java.util.stream.SpinedBuffer.asArray(SpinedBuffer.java:215) at java.util.stream.Nodes$SpinedNodeBuilder.asArray(Nodes.java:1296) at java.util.stream.ReferencePipeline.toArray(ReferencePipeline.java:439) at nachbearbeitung.CheckExistingMAIDs.main(CheckExistingMAIDs.java:41)

Thanks in advance!

Tagir Valeev
  • 97,161
  • 19
  • 222
  • 334
Klaster
  • 673
  • 1
  • 7
  • 17
  • Can you share the full stacktrace please? – Mureinik Sep 30 '17 at 13:00
  • My bad! Thanks for the hint. It is a java.lang.ArrayStoreException Error – Klaster Sep 30 '17 at 13:02
  • 1
    This may be a duplicate of [Dealing with an ArrayStoreException](https://stackoverflow.com/questions/12369957/dealing-with-an-arraystoreexception). Unfortunately, I've never seen this error before, so I can't help with it beyond that link. – Carcigenicate Sep 30 '17 at 13:05
  • 5
    Here is the documentation of Files.walk: https://docs.oracle.com/javase/8/docs/api/java/nio/file/Files.html#walk-java.nio.file.Path-java.nio.file.FileVisitOption...-. It returns a Stream. You're trying to store these Paths into an Array of Files. So that can't work. Bananas go in banana boxes. Eggs go in egg boxes. Same here. – JB Nizet Sep 30 '17 at 13:11
  • Thanks JB. That did the trick. From the Path-Object, you can get the FileName, but that's still a Path Object. To get the String you have to add .toString(). – Klaster Sep 30 '17 at 13:39

2 Answers2

5

An ArrayStoreException is not specific to Java streams, it's very old Java Exception which means that you want to store an element of incompatible type inside an array. In your case you want to create an array of File objects. But in fact you are trying to store Path objects there, as Files.walk produces a Stream<Path>, not Stream<File>. To convert a Path to a File you may use Path.toFile method calling it in the map step:

File[] files = Files.walk(Paths.get("."))
        .filter(Files::isRegularFile)
        .map(Path::toFile)
        .toArray(File[]::new);
Tagir Valeev
  • 97,161
  • 19
  • 222
  • 334
2

To list only file names:

List<Path> pathList = Files.walk(Paths.get(path))
                           .filter(Files::isRegularFile)
                           .collect(Collectors.toList());

pathList.forEach(p -> System.out.println(p.getFileName()));

Can't store a method's local variable in a Stream: .forEach(p -> existingNames.add(p.getFileName()));