How do I detect whether the file system is case-sensitive?
Asked Answered
E

6

17

I have a List<String> of file names from a folder and a certain file name as String. I want to detect whether the file name is in the list, but need to respect the underlying file system's property of whether it is case-sensitive.

Is there any easy way to do this (other than the "hack" of checking System.getProperty("os.name", "").toLowerCase().indexOf("windows")!=-1)? ;-)

Erysipelas answered 17/8, 2009 at 13:58 Comment(1)
Note that "case insensitive filesystem" is not equivalent to "OS is Windows", anyway. All of Windows, Linux and Mac OS can use either case-sensitive or case-insensitive filesystems; don't confuse the concepts. The "hack" would be to assert that a lowercase filename doesn't exist; create a (temporary) file with that name in uppercase, then check if the lowercase-named file exists.Stasiastasis
C
12

Don't use Strings to represent your files; use java.io.File:

http://java.sun.com/javase/6/docs/api/java/io/File.html#equals(java.lang.Object)

Cyclamate answered 17/8, 2009 at 14:15 Comment(3)
As an additional note, you can get an array of files from a directory using File's listFiles() method on a File object for said directory. This can then be manipulated as an array or converted to a list using Arrays.asListHeyman
I don't think this answer works in the OS X case. OS X appears to use a UnixFileSystem as its FileSystem implementation regardless of whether the File is on a case sensitive or insensitive HFS+ filesystem. Therefore, File.equals(File) will return false on a case insensitive file system when filenames with differing cases are passed. Edit: just noticed @SaM said the same thing in another answer.Facula
In the end I found a convoluted way of using File.exists (which does seem to obey the filesystem's case rules) was the only way.Facula
Z
3
boolean isFileSystemCaseSensitive = !new File( "a" ).equals( new File( "A" ) );
Zink answered 17/6, 2010 at 22:2 Comment(2)
Have just tested this on Mac OSX, default case insensitive file system and it doesn't return the expected result.Photophilous
With the note that it doesn't take the file system in account, just the OS - this answer is no worse than accepted one. As long as you are aware of it's fine. I'll take it as I couldn't find better solution that takes FS in account. +1Hampshire
F
2

It looks like you can use the IOCase.

Federico answered 2/12, 2010 at 3:39 Comment(1)
Again - doesn't work for OS X very well. Just assumes case sensitive, because the file separators are forward slashes! See this discussion between the devs for more: issues.apache.org/jira/browse/IO-171Facula
M
1

Write a file named "HelloWorld"; attempt to read a file named "hELLOwORLD"?

Monostrophe answered 17/8, 2009 at 14:1 Comment(0)
P
0

I don't think any of the existing examples actually handle this properly, you need to write the file to disk.

    private boolean caseSensitivityCheck() {
    try {
        File currentWorkingDir = new File(System.getProperty("user.dir"));
        File case1 = new File(currentWorkingDir, "case1");
        File case2 = new File(currentWorkingDir, "Case1");
        case1.createNewFile();
        if (case2.createNewFile()) {
            System.out.println("caseSensitivityCheck: FileSystem of working directory is case sensitive");
            case1.delete();
            case2.delete();
            return true;
        } else {
            System.out.println("caseSensitivityCheck: FileSystem of working directory is NOT case sensitive");
            case1.delete();
            return false;
        }
    } catch (IOException e) {
        throw new RuntimeException(e);
    }
}
Polash answered 11/10, 2019 at 23:27 Comment(0)
C
0

You can use the following static method:

/**
 * <p>
 * Checks, whether the provided path points to a case-sensitive file system or not.
 * </p>
 * <p>
 * It does so by creating two temp-files in the provided  path and comparing them. Note that you need to have write
 * access to the provided path.
 *
 * @param pathToFileSystem path to the file system to test
 * @param tmpFileName      name of the temp file that is created
 * @return {@code true}, if the provided path points to a case-sensitive file system; {@code false} otherwise
 * @throws IOException if IO operation fails
 */
public static boolean fileSystemIsCaseSensitive(Path pathToFileSystem, String tmpFileName) throws IOException {

    Path a = Files.createFile(pathToFileSystem.resolve(Paths.get(tmpFileName.toLowerCase())));
    Path b = null;
    try {
        b = Files.createFile(pathToFileSystem.resolve(Paths.get(tmpFileName.toUpperCase())));
    } catch (FileAlreadyExistsException e) {
        return false;
    } finally {
        Files.deleteIfExists(a);
        if (b != null) Files.deleteIfExists(b);
    }
    return true;
}

Use it as follows:

@Test
void fileSystemIsCaseSensitive01() throws IOException {
    assertTrue(Util.fileSystemIsCaseSensitive(Paths.get("/Volumes/Case-sensitive-Volume/Data"), "a"));
}

@Test
void fileSystemIsCaseSensitive02() throws IOException {
    assertFalse(Util.fileSystemIsCaseSensitive(Paths.get("/Volumes/Case-insensitive-Volume/Data"), "a"));
}

Note the different volumes provided (Case-sensitive-Volume vs. Case-insensitve-Volume).

Cowbird answered 6/11, 2022 at 14:4 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.