获取文件区分大小写的名称,不区分大小写拼写

时间:2012-01-05 21:22:41

标签: java string file io

我正在创建一个用户从中选择文件的应用程序:

FilePicker.PickFile(filename)

其中filename是一个字符串。

在该方法中,它将转换为:

File file = new File(filename);

并没有错。接下来,我做,

if(file.exists()){
    System.out.println(file.getName());
}
else{
    System.out.println("Fail.");
}

这就是问题的开始。我想得到文件的名称,说" HELLO.txt,"但如果filename是" hello.txt,"它仍然通过file.exists()检查,file.getName()返回" hello.txt,"不是" HELLO.txt"。有没有办法,将file.getName()作为区分大小写的版本返回" HELLO.txt?"谢谢!

示例:

HELLO.txt is the real file

FilePicker.PickFile("hello.txt");

输出:

hello.txt

3 个答案:

答案 0 :(得分:7)

当您使用Windows(保留大小写(FAT32 / NTFS / ..))时,您可以使用file.getCanonicalFile() .getName()来获取所选文件的规范名称。

当您使用Linux或Android并且想要根据不一定匹配大小写的文件名选择文件时,请遍历文件目录(file.getParent())中的所有文件,然后选择一个.equalsIgnoreCase filename。或者参见Case-insensitive File.equals on case-sensitive file system

答案 1 :(得分:1)

/**
 * Maps lower case strings to their case insensitive File
 */
private static final Map<String, File> insensitiveFileHandlerCache = new HashMap<String, File>();

/**
 * Case insensitive file handler. Cannot return <code>null</code>
 */
public static File newFile(String path) {
    if (path == null)
        return new File(path);
    path = path.toLowerCase();
    // First see if it is cached
    if (insensitiveFileHandlerCache.containsKey(path)) {
        return insensitiveFileHandlerCache.get(path);
    } else {
        // If it is not cached, cache it (the path is lower case)
        File file = new File(path);
        insensitiveFileHandlerCache.put(path, file);

        // If the file does not exist, look for the real path
        if (!file.exists()) {

            // get the directory
            String parentPath = file.getParent();
            if (parentPath == null) {
                // No parent directory? -> Just return the file since we can't find the real path
                return file;
            }

            // Find the real path of the parent directory recursively
            File dir = Util.newFile(parentPath);

            File[] files = dir.listFiles();
            if (files == null) {
                // If it is not a directory
                insensitiveFileHandlerCache.put(path, file);
                return file;
            }

            // Loop through the directory and put everything you find into the cache
            for (File otherFile : files) {
                // the path of our file will be updated at this point
                insensitiveFileHandlerCache.put(otherFile.getPath().toLowerCase(), otherFile);
            }

            // if you found what was needed, return it
            if (insensitiveFileHandlerCache.containsKey(path)) {
                return insensitiveFileHandlerCache.get(path);
            } 
        }
        // Did not find it? Return the file with the original path
        return file;
    }
}

使用

File file = newFile(path);

而不是

File file = new File(path);

它由缓存支持,所以它不应该太慢。做了一些试运行,它似乎工作。它以递归方式检查父目录,看它们是否有正确的字母大小写。然后它为每个目录列出所有文件并缓存其正确的字母大小写。最后,它检查是否找到了包含路径的文件,并返回带有区分大小写路径的文件。

答案 2 :(得分:-1)

在Windows上的Java 7及更高版本中,您可以使用Path#toRealPath(NOFOLLOW_LINKS),并且在存在符号链接的情况下,它会比getCanonicalFile()更正确。