RFR: 8298318: (fs) APIs for handling filename extensions [v2]
Anthony Vanelverdinghe
duke at openjdk.org
Thu Nov 30 10:33:12 UTC 2023
On Mon, 20 Nov 2023 23:30:45 GMT, Brian Burkhalter <bpb at openjdk.org> wrote:
>> Add to `java.nio.file.Path` a method `getExtension` to retrieve the `Path`'s extension, and companion methods `removeExtension` and `addExtension`.
>
> Brian Burkhalter has updated the pull request with a new target base due to a merge or a rebase. The incremental webrev excludes the unrelated changes brought in by the merge/rebase. The pull request contains three additional commits since the last revision:
>
> - 8298318: Correct type in path.getExtension spec
> - Merge
> - 8298318: (fs) APIs for handling filename extensions
The more I think about it, the more I'm convinced that the concept of a filename is sufficiently complex to warrant its own type. Moreover, I believe extension-specific APIs would be out of place in `Path`, as they apply to a single name, whereas `Path` is all about a sequence of names. While an additional type would increase the API surface, the existing `Path::getFileName` can be repurposed (if I'm correct that the proposed change would be a compatible one).
So I'd like to propose:
* introducing an interface `Filename` which extends `Path` and `CharSequence`
* changing `Path::getFileName` to return an instance of `Filename`
where `Filename` would look something like below and would allow code such as:
var foo = Path.of(".foo.tar.gz").getFileName();
if(foo.extension().equals(".gz") && foo.base().extension().equals(".tar")) {
var name = foo.base().base();
assert "foo".contentEquals(name);
}
/**
* Represents a filename.
*
* Invariant (pseudocode): hidden() + base() + extension() = toString()
*/
interface Filename extends Path, CharSequence {
/**
* An enum that allows overriding how the filename must be interpreted.
*/
enum DotOption {
HIDDEN_MARKER_AS_LEADING_DOT,
NO_HIDDEN_MARKER
}
/**
* {@return the hidden marker}
*
* If this instance represents a Filename where a leading dot serves as a "hidden" marker
* or DotOption.HIDDEN_MARKER_AS_LEADING_DOT is specified,
* returns `Optional.of(...)`
* If this instance represents a Filename where a leading dot has no special meaning
* or DotOption.NO_HIDDEN_MARKER is specified,
* returns `Optional.empty()`
*/
Optional<Boolean> hidden(DotOption... options);
/**
* {@return the filename without the hidden marker and the file extension}
*/
Filename base();
/**
* {@return the file extension including the dot}
*
* The filenames `.` and `..` don't have an extension.
*
* For filenames with a single, leading dot:
* If this instance represents a Filename where a leading dot serves as a "hidden" marker
* or DotOption.HIDDEN_MARKER_AS_LEADING_DOT is specified,
* returns the empty String
* If this instance represents a Filename where a leading dot has no special meaning
* or DotOption.NO_HIDDEN_MARKER is specified,
* returns the whole filename
*
* For any other filenames, the extension is the substring starting at the last dot.
*/
String extension(DotOption... options);
// TODO: consider additional methods such as withExtension, withoutExtension, ...
}
-------------
PR Comment: https://git.openjdk.org/jdk/pull/16226#issuecomment-1833489866
More information about the nio-dev
mailing list