RFR: 8298318: (fs) APIs for handling filename extensions [v4]
Roger Riggs
rriggs at openjdk.org
Fri Mar 8 16:34:55 UTC 2024
On Thu, 7 Mar 2024 21:23:11 GMT, Brian Burkhalter <bpb at openjdk.org> wrote:
>> src/java.base/share/classes/java/nio/file/Path.java line 324:
>>
>>> 322: * This method must satisfy the invariant:
>>> 323: * {@snippet lang="java" :
>>> 324: * assert equals(Path.of(withoutExtension().toString()
>>
>> I'm an author of an HTTP filesystem provider and would like to use these new methods since they address longstanding pain points working with Paths. However, my usage wouldn't be able to satisfy this requirement.
>>
>> Here's an example of on our path strings: `http://example.com/subfolder/file.txt?language=english`
>>
>> In this case, the filename is `file.txt` and the query parameters (`?language=english`) are not considered part of the filename.
>> This invariant doesn't work for such a path.
>>
>> withoutExtension() == "http://example.com/subfolder/file?language=english"
>> getExtension() == "txt"
>>
>> So it would end up looking like:
>>
>> Path.of("http://example.com/subfolder/file?language=english" + ".txt"). == "http://example.com/subfolder/file?language=englis.txt"
>>
>>
>> I think the invariant might be better written something like this:
>>
>>
>> path.equals(path.withExtension(path.getExtension())
>>
>>
>> As an aside, it's not generally true that `Path.of(path.toString()).equals(path)`. This is because a `Path.of` always creates a Path from the default filesystem provider. So if you have a Path from an alternate provider and call Path.of(altPath.toString) you get a completely different Path object with a different provider. if you are going to require invariants on the toString behavior you probably have to specify that it only applies to the default FileSystemProvider.
>>
>> To construct more general Path implementations you have to use the `Path.of(URI)` method instead of `Path.of(String)` so it would probably be better to refer to that.
>
> As for the example "http://example.com/subfolder/file.txt?language=english", this is what I see at present:
>
> jshell> Path p = Path.of("http://example.com/subfolder/file.txt?language=english")
> p ==> http:/example.com/subfolder/file.txt?language=english
>
> jshell> p.withoutExtension()
> $2 ==> http:/example.com/subfolder/file
>
> jshell> p.getExtension()
> $3 ==> "txt?language=english"
>
> jshell> p.withoutExtension().toString() + "." + p.getExtension()
> $4 ==> "http:/example.com/subfolder/file.txt?language=english"
>
> jshell> p.withExtension(p.getExtension())
> $5 ==> http:/example.com/subfolder/file.txt?language=english
>
> The two forms of the invariant appear satisfied.
>
> Good point about non-default providers.
I would think that manipulations of filename components of a URI/URL would require extracting/converting to a file path first. Path applies to file system names. One could imagine a FileSystem whose Paths were URIs and then yes it could/should implement the file extension related methods to manipulate the file extension and produce valid URIs.
-------------
PR Review Comment: https://git.openjdk.org/jdk/pull/16226#discussion_r1517957022
More information about the nio-dev
mailing list