-1

I'm trying the retrieve the last modified file name with a matching pattern starts with Order_ and there should not be any hidden files, however it throws compilation error.

try {
    File dir = new File("< dir >");
    if (!dir.isDirectory()) {
        Optional<File> op = Arrays.stream(dir.listFiles(File::isFile))
                .max((f1, f2) -> Long.compare(f1.lastModified(), f12lastModified()))
                .filter(fl -> fl.getName().startsWith("Order_") && !fl.getCanonicalPath().endsWith("~"))
        ; // Unhandled exception compilation error for canonicalPath method 
    }
} catch (Exception e) {
}
Exception: Unhandled exception: java.io.IOException

Any ideas would be greatly appreciated.

Syed
  • 2,471
  • 10
  • 49
  • 89
  • Please include the error in your question. – Lino Jun 08 '21 at 11:05
  • 1
    Also the `“` and `”` characters are not valid `String` literalts, they should be replaced with `"` – Lino Jun 08 '21 at 11:06
  • 1
    Does this answer your question? [Java 8: Lambda-Streams, Filter by Method with Exception](https://stackoverflow.com/questions/19757300/java-8-lambda-streams-filter-by-method-with-exception) – RubioRic Jun 08 '21 at 11:16
  • @Lino, the quotes were added as part of typing. They are valid quotes in the editor – Syed Jun 08 '21 at 11:33
  • @Abra, yes its a compilation error. – Syed Jun 08 '21 at 11:33
  • Maybe you should use method [list](https://docs.oracle.com/javase/8/docs/api/java/nio/file/Files.html#list-java.nio.file.Path-), in class `java.nio.file.Files`, instead of method `listFiles` in class `File`? – Abra Jun 08 '21 at 11:40

1 Answers1

2

This feels like lambda abuse (using a hammer to butter your toast instead of, you know, a butter knife, because you just bought it and it's all shiny and new).

.max() returns either 1, or 0, elements, in the form of an Optional. you then filter that optional to check if the naming is right.

In other words, if the most recently modified file so happens to not start with Order_, this all returns Optional.NONE which surely wasn't your intent. You want to flip your max and your filter line.

More generally, you don't want to do this with lambdas. Inline Lambdas are the lesser evil - they are not exception transparent, not mutable local variable transparent, and not control flow transparent.

These 3 properties are fantastic when a lambda represents code that will run in some other context (e.g. another thread or much later). They are downsides when the code is going to be run then and there.

That means that when a lambda-based strategy and a non-lambda-based strategy for an inline code concept are roughly equally good, then you should prefer the non-lambda-based strategy. This becomes particularly poignant here, as the code is using obsolete API (the old java.io.File API, instead of the newer java.nio.file API).

In this case, .getCanonicalPath() is slightly odd behaviour: The only functional difference between invoking fl.getName().endsWith(...) and fl.getCanonicalPath().endsWith(...) is that the latter will first follow the link if the referenced 'file' is a soft-link.

That sounds like soft-links matter, and if they matter, you don't want this API as it is wonky and ill defined in the face of soft-links. The new API deals with it better, you'd want to use that (java.nio.file.Files's walk method, for example). If soft linking doesn't matter, then it's easy: Replace .getCanonicalPath() with .getName() and all is well. Well, after you fix your bug and flip the filter and max lines back in their right positions.

Note also that .getCanonicalPath() is slow - it needs to hit the disk, or at least, it might. (It will if it is a soft-link; the API doesn't define whether it will in other cases. The JVM impl is free to hit disk on some OSes and not on others. It may run blazingly fast on your system and run dog slow on another, making it hard to test).

rzwitserloot
  • 85,357
  • 5
  • 51
  • 72
  • Thanks. There were some corrupted or hidden files in the same directory,so I don't want to consider ~ files. I tried flipping filter with max, still the compilation error is available. – Syed Jun 08 '21 at 11:40