Filesystem case sensitive check and java.io.File#equals

Jaikiran Pai jai.forums2013 at gmail.com
Wed Nov 7 14:27:25 UTC 2018


Hi Alan,

On 07/11/18 7:15 PM, Alan Bateman wrote:
> On 07/11/2018 13:13, Jaikiran Pai wrote:
>> :
>>
>>
>> My impression, based on that javadoc, was that the implementation of
>> that API will use the underlying _filesystem_ to decide whether or not
>> its case sensitive. However, my experiments on a macOS which is case
>> insensitive and also a basic check of the implementation code in the
>> JDK, shows that this uses a lexicographic check on the string
>> representation of the paths. Is that what this javadoc means by
>> "underlying system". I understand that there's a further sentence in
>> that javadoc which says UNIX systems are case significant and Windows
>> isn't. However, it wasn't fully clear to me that this API wouldn't
>> delegate it to the underlying filesystem on the OS.
> Maybe the javadoc could be clearer but having an equals method
> delegate to the underlying file system would be very problematic
> (think URL equals or cases where the file path is relative or doesn't
> locate a file).

I see what you mean. About the javadoc, do you think it is worth
improving and if so, should I file an enhancement at bugs.java.com?

>
>> While we are at it, is there a better API that can be used to do such a
>> case sensitivity check of the underlying filesystem? I checked the APIs
>> in java.nio.file but couldn't find anything relevant. If there isn't any
>> such API currently, is that something that can be introduced?
>>
> This has been looked into a couple of times over the years,
> suggestions have included FileStore exposing a comparator that uses
> the rules of a specific underlying file system or volume. This turns
> out to be very complicated as it means looking beyond case sensitively
> issues and into topics such as case preservation, Unicode
> normalization forms, per volume case mapping tables, and handling of
> limits and truncation.
So I guess, that leaves us (the client applications) to rely on some
kind of file creation tricks like the one below to figure this out:

        // create a temp file in a fresh directory
        final Path tmpDir = Files.createTempDirectory(null);
        final Path tmpFile = Files.createTempFile(tmpDir, null, null);
        tmpFile.toFile().deleteOnExit();
        tmpDir.toFile().deleteOnExit();
        // now check if a file with that same name but different case is
considered to exist
        final boolean existsAsLowerCase =
Files.exists(Paths.get(tmpDir.toString(),
tmpFile.getFileName().toString().toLowerCase()));
        final boolean existsAsUpperCase =
Files.exists(Paths.get(tmpDir.toString(),
tmpFile.getFileName().toString().toUpperCase()));
        // if the temp file that we created is found to not exist in a
particular "case", then
        // the filesystem is case sensitive
        final boolean filesystemCaseSensitive = existsAsLowerCase ==
false || existsAsUpperCase == false;

One final question - is there anywhere in the JDK code, where files are
auto created (for whatever purpose)? If such a construct exists, maybe
during the initialization of each FileStore implementation, it could do
such tricks (maybe in a much better and performant way) and figure out
this detail and then expose it some way? It feels hacky to do it in the
JDK, so I fully understand if such a construct won't be entertained.

-Jaikiran





More information about the core-libs-dev mailing list