我正在创建一个用户从中选择文件的应用程序:
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
答案 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()更正确。