Java文件存在区分大小写的.jpg和.JPG

Se *_*ong 20 java

我使用此函数来检测我的文件是否存在.虽然我有一些图像存储为.jpg,.JPG,.png和.PNG.但即使真实文件具有扩展名.JPG或.PNG,它也总是返回.jpg或.png为真.

在我将其呈现到我的网页后,它会抛出错误"无法加载资源:服务器响应状态为404(未找到)".

public static String getPhotoFileExtension(int empKey){
    try{
        String[] types = {".jpg",".JPG",".png", ".PNG"};
        for(String t : types)
        {
            String path = "/"+Common.PHOTO_PATH + empKey + t;
            File f = new File(Sessions.getCurrent().getWebApp()
                    .getRealPath(path));
            if(f.isFile()) 
                return t;
        }
    }catch (Exception e) {
        e.printStackTrace();
    }
    return "";
}
Run Code Online (Sandbox Code Playgroud)

Arc*_*ord 19

因此,您希望获得存储在文件系统中的文件的真实区分大小写的名称.让我们有成像,我们有以下路径:

  • Linux上:使用ext4(区分大小写)/testFolder/test.PnG
  • Windows上使用NTFS(区分大小写)c:\testFolder\test.PnG

现在让我们File为每个图像文件创建一些Java 对象.

// on Linux
File f1 = new File("/testFolder/test.png");
File f2 = new File("/testFolder/test.PNG");
File f3 = new File("/testFolder/test.PnG");
f1.exists(); // false
f2.exists(); // false
f3.exists(); // true

// on Windows
File f1 = new File("c:\\testFolder\\test.png");
File f2 = new File("c:\\testFolder\\test.PNG");
File f3 = new File("c:\\testFolder\\test.PnG");
f1.exists(); // true
f2.exists(); // true
f3.exists(); // true
Run Code Online (Sandbox Code Playgroud)

您的问题是,所有File类似的调用File.exists都被重定向到java.io.FileSystem代表文件系统的实际操作系统调用的类JVM.所以你无法区分Windows机器test.PNGtest.png.Windows本身也不是.

即使在Windows上,每个文件在文件系统中都有一个已定义的名称,例如:test.PnG.Windows Explorer如果键入,您将在您的或命令行中看到此信息dir c:\testFolder.

因此,您可以在Java 中执行的操作是使用该File.list方法parent directory导致操作系统列表调用此目录中的所有文件及其真实名称.

File dir = new File("c://testFolder//");
for(String fileName : dir.list())
    System.out.println(fileName);
// OUTPUT: test.PnG
Run Code Online (Sandbox Code Playgroud)

或者如果你喜欢File对象

File dir = new File("c://testFolder//");
for(File file : dir.listFiles())
    System.out.println(file.getName());
// OUTPUT: test.PnG
Run Code Online (Sandbox Code Playgroud)

您可以使用它来编写自己的exists在所有操作系统上区分大小写的方法

public boolean exists(File dir, String filename){
    String[] files = dir.list();
    for(String file : files)
        if(file.equals(filename))
            return true;
    return false;
}
Run Code Online (Sandbox Code Playgroud)

像这样使用它:

File dir = new File("c:\\testFolder\\");
exists(dir, "test.png");   // false
exists(dir, "test.PNG");   // false
exists(dir, "test.PnG");   // true
Run Code Online (Sandbox Code Playgroud)



编辑:我不得不承认我错了.有一种方法可以获得文件的真实名称.我总是忽略这个方法File.getCanonicalPath.
再一次我们的例子:我们有那个文件c:\testFolder\test.PnG.

File f = new File("c://testFolder//test.png");
System.out.println(f.getCanonicalPath());
// OUTPUT: C:\testFolder\test.PnG
Run Code Online (Sandbox Code Playgroud)

有了这些知识,您就可以为区分大小写的扩展编写一个简单的测试方法,而无需迭代所有文件.

public boolean checkExtensionCaseSensitive(File _file, String _extension) throws IOException{
    String canonicalPath = _file.getCanonicalPath();
    String extension = "";
    int i = canonicalPath.lastIndexOf('.');
    if (i > 0) {
        extension = canonicalPath.substring(i+1);
        if(extension.equals(_extension))
            return true;
    }
    return false;
}
Run Code Online (Sandbox Code Playgroud)

像这样使用它:

File f = new File("c://testFolder//test.png");    
checkExtensionCaseSensitive(f, "png"); // false
checkExtensionCaseSensitive(f, "PNG"); // false
checkExtensionCaseSensitive(f, "PnG"); // true
Run Code Online (Sandbox Code Playgroud)

  • 至少在我的设置中,“File.getCanonicalPath()”并不是获取真实文件名的可靠方法。我编写了一个小类,它将“File.getCanonicalPath()”的结果重复打印到 Eclipse 控制台。当程序运行时,将文件“abc.txt”重命名为“Abc.txt”会导致“getCanonicalPath()”仍然返回“abc.txt”,直到我重新启动程序/JVM。我的设置是 JDK 6u45 和 Windows 10。我必须使用基于表达式“ArrayUtils.contains(parentFile.list(), realFileName)”的解决方案。 (2认同)

NiM*_*Thr 5

如果您正在寻找一个可以在任何平台上确定文件存在且区分大小写的函数;这应该做到这一点:

public static boolean fileExistsCaseSensitive(String path) {
    try {
        File file = new File(path);
        return file.exists() && file.getCanonicalFile().getName().equals(file.getName());
    } catch (IOException e) {
        return false;
    }
}
Run Code Online (Sandbox Code Playgroud)