Common I/O Tasks in Modern Java
dev.java
dev.java
try (Stream<String> lines = Files.lines(path)) {
...
}
has a catch (pun not intended ;)), in that if you write catch (IOException ex) {
... handle it ...
}
this surprisingly only catches I/O errors thrown directly by the lines() method, but not those thrown during the stream processing, since those are UncheckedIOExceptions. This is because the Stream API designers decided (very unfortunately, IMO) to not want to deal with checked exceptions.I therefore prefer using Files::newBufferedReader and BufferedReader::readLine.
———
The `new Scanner(path)` example is arguably even worse, because upon I/O error the tokens() implementation simply behaves as if the end of the file was reached, and you have to manually check with Scanner::ioException if an error occurred.
There was something more fucked up about the URL API which I can not remember. I think it triggers blocking DNS resolution on construction or something. Haven't written Java for more than 10 years though. Might be mixing something up.
It's a shame that Java missed the opportunity to duplicate all functionality expect the absurd equality on URI (including weirdos like openStream), so that the old URL could properly focus on celebrating xkcd:1172:workflow without doing too much harm.
What's the sin of File by the way, besides not being quite as convenient when interacting with modern API? Unfortunately the article is very silent about why it needed to be substituted instead of extended. I smell a similar story as URL vs URI, just not quite as bad?
In particular, File conflates several concepts: a filesystem, a path to a file in that filesystem, and a file's contents as byte streams. Path only represents a path, you need to use a FileSystem object to read from a file at that path, and you get a Channel for reading/writing that is used to fill a Buffer.
However, File does not need to be substituted. java.io is not deprecated nor is it slated for deprecation, and there are easy ways to convert from File to Path and vice-versa.
As you said, File won't go away. But it really does not feel right to not have File implement Path, or perhaps a subset of Path that would be good enough for all those use cases where something outside the identifier acts on the identified entity. Every .toFile() and .toPath() is a little defeat in API evolution, and there are a lot of those. Do they consider addition of an new interface, to an existing class a break of compatibility? On 17 windows (that's what I happen to be looking at), a chain of toPath/toFile/toPath won't even give you a symmetrically bound pair of immutables, toPath is memoized but toFile is not. Should not have been too hard keeping a provenience reference on the other side, or have memoization on both sides?
https://docs.oracle.com/javase/8/docs/api/java/net/URL.html#...
(I do not miss working in Java haha)
Rust I/O feels like it was inspired heavily by Java's I/O and it owes a lot of credit.
FileSystem from Zip, i did know that. Does it also work for writing?
And people use var nowadays. Pity, val has not found its way into java.
And i wish for more useful stream operators, which can lift streams up, like groups. And tee is finally in it, but looks a bit bloated when being used.
And parallelStreams(), people always forget, that it is not good for long running tasks. You always block the default executor.
But in general, iam happy with the progress. We have pressure from Kotlin, but so far, i have not felt the desire to switch.