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

时间:2016-01-05 02:57:45

标签: 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 "";
}

5 个答案:

答案 0 :(得分:18)

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

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

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

// 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

您的问题是所有File File.exists的来电被重定向到java.io.FileSystem类,代表JVM文件系统的实际操作系统调用。因此,您无法在{1}}和test.PNG之间区分Windows计算机。 Windows本身也不是。

即使在Windows上,每个文件在文件系统中都有一个已定义的名称,例如:test.png。如果您输入test.PnG,则会在Windows Explorer或命令行中看到此信息。

因此,您可以在Java中使用dir c:\testFolder上的File.list方法,该方法会导致操作系统列表调用此目录中的所有文件及其真实姓名。

parent directory

或者您更喜欢File dir = new File("c://testFolder//"); for(String fileName : dir.list()) System.out.println(fileName); // OUTPUT: test.PnG 对象

File

您可以使用它来编写自己的File dir = new File("c://testFolder//"); for(File file : dir.listFiles()) System.out.println(file.getName()); // OUTPUT: test.PnG 方法,该方法在所有操作系统上都区分大小写

exists

像这样使用:

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



编辑:我不得不承认我错了。有一种方法可以获得文件的真实名称。我总是忽略方法File dir = new File("c:\\testFolder\\"); exists(dir, "test.png"); // false exists(dir, "test.PNG"); // false exists(dir, "test.PnG"); // true 我们再举个例子:我们有文件File.getCanonicalPath

c:\testFolder\test.PnG

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

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

像这样使用:

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;
}

答案 1 :(得分:4)

如果您正在寻找一种能够在任何平台上确定文件存在且区分大小写的功能;这应该这样做:

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;
    }
}

答案 2 :(得分:3)

我开始讨论这个因为我之前没有使用过Apache的IOFileFilter,并且认为我会添加这个解决方案作为一个机会来玩它。

以下是代码:

import java.io.File;
import java.util.Collection;
import java.util.Optional;

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.filefilter.IOFileFilter;

public class CaseInsensitiveFileFinder {

    /**
     * Attempts to find a file with the given <code>fileName</code> (irrespective of case) in the given
     * <code>absoluteDirPath</code>. Note that while this method is able to find <code>fileName</code> ignoring case, it
     * may not be able to do so if <code>absoluteDirPath</code> is in an incorrect case - that behavior is OS dependent.
     * 
     * @param absoluteDirPath the absolute path of the parent directory of <code>fileName</code> (e.g. "/Users/me/foo")
     * @param fileName the name of the file including extension that may or may not be the correct case
     * (e.g. myfile.txt)
     * @return an optional reference to the file if found, {@link Optional#empty()} will be returned if the file is not
     * found
     */
    public Optional<File> findFileIgnoreCase(String absoluteDirPath, final String fileName) {

        File directory = new File(absoluteDirPath);
        if (!directory.isDirectory()) {
            throw new IllegalArgumentException("Directory '" + absoluteDirPath + "' isn't a directory.");
        }
        IOFileFilter caseInsensitiveFileNameFilter = new IOFileFilter() {
            @Override
            public boolean accept(File dir, String name) {
                boolean isSameFile = fileName.equalsIgnoreCase(name);
                return isSameFile;
            }

            @Override
            public boolean accept(File file) {
                String name = file.getName();
                boolean isSameFile = fileName.equalsIgnoreCase(name);
                return isSameFile;
            }
        };
        Collection<File> foundFiles = FileUtils.listFiles(directory, caseInsensitiveFileNameFilter, null);
        if (foundFiles == null || foundFiles.isEmpty()) {
            return Optional.empty();
        }
        if (foundFiles.size() > 1) {
            throw new IllegalStateException(
                    "More requirements needed to determine what to do with more than one file. Pick the closest match maybe?");
        }
        // else exactly one file
        File foundFile = foundFiles.iterator().next();
        return Optional.of(foundFile);
    }
}

以下是一些测试用例:

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

import java.io.File;
import java.io.IOException;
import java.util.Optional;

import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.StringUtils;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;

import com.google.common.io.Files;

/**
 * Non-quite-unit tests for {@link CaseInsensitiveFileFinder} class.
 */
public class CaseInsensitiveFileFinderTest {

    private static String APPENDABLE_NEW_TMP_DIR_PATH;

    /**
     * Create the files with different cases.
     * @throws IOException 
     */
    @BeforeClass
    public static void setup() throws IOException {
        File newTmpDir = Files.createTempDir();
        String newTmpDirPath = newTmpDir.getCanonicalPath();
        final String appendableNewTmpDirPath;
        String fileSeparator = System.getProperty("file.separator");
        if (!newTmpDirPath.endsWith(fileSeparator)) {
            appendableNewTmpDirPath = newTmpDirPath + fileSeparator;
        }
        else {
            appendableNewTmpDirPath = newTmpDirPath;
        }
        CaseInsensitiveFileFinderTest.APPENDABLE_NEW_TMP_DIR_PATH = appendableNewTmpDirPath;

        File foofileDotPng = new File(appendableNewTmpDirPath + "FOOFILE.PNG");
        Files.touch(foofileDotPng);
        assertTrue(foofileDotPng.isFile());
        File barfileDotJpg = new File(appendableNewTmpDirPath + "BARFILE.JPG");
        Files.touch(barfileDotJpg);
        assertTrue(barfileDotJpg.isFile());
    }

    @AfterClass
    public static void teardown() throws IOException {
        File newTmpDir = new File(CaseInsensitiveFileFinderTest.APPENDABLE_NEW_TMP_DIR_PATH);
        assertTrue(newTmpDir.isDirectory());
        // delete even though directory isn't empty
        FileUtils.deleteDirectory(newTmpDir);
    }

    @Test
    public void findFooFilePngUsingLowercase() throws IOException {
        CaseInsensitiveFileFinder fileFinder = new CaseInsensitiveFileFinder();
        Optional<File> optFoundFile = fileFinder.findFileIgnoreCase(APPENDABLE_NEW_TMP_DIR_PATH, "foofile.png");
        assertTrue(optFoundFile.isPresent());
        File foundFile = optFoundFile.get();
        assertTrue(foundFile.isFile());
        assertEquals(APPENDABLE_NEW_TMP_DIR_PATH + "FOOFILE.PNG", foundFile.getCanonicalPath());
    }

    @Test
    public void findBarFileJpgUsingLowercase() throws IOException {
        CaseInsensitiveFileFinder fileFinder = new CaseInsensitiveFileFinder();
        Optional<File> optFoundFile = fileFinder.findFileIgnoreCase(APPENDABLE_NEW_TMP_DIR_PATH, "barfile.jpg");
        assertTrue(optFoundFile.isPresent());
        File foundFile = optFoundFile.get();
        assertTrue(foundFile.isFile());
        assertEquals(APPENDABLE_NEW_TMP_DIR_PATH + "BARFILE.JPG", foundFile.getCanonicalPath());
    }

    @Test
    public void findFileThatDoesNotExist() {
        CaseInsensitiveFileFinder fileFinder = new CaseInsensitiveFileFinder();
        Optional<File> optFoundFile = fileFinder.findFileIgnoreCase(APPENDABLE_NEW_TMP_DIR_PATH, "dne.txt");
        assertFalse(optFoundFile.isPresent());
    }

    @Test
    public void findFooFileUsingDirWithNoTrailingFileSeparator() throws IOException {
        CaseInsensitiveFileFinder fileFinder = new CaseInsensitiveFileFinder();
        String newDirPathWithNoTrailingFileSep = StringUtils.chop(APPENDABLE_NEW_TMP_DIR_PATH);
        Optional<File> optFoundFile = fileFinder.findFileIgnoreCase(newDirPathWithNoTrailingFileSep, "FOOFILE.PNG");
        assertTrue(optFoundFile.isPresent());
        File foundFile = optFoundFile.get();
        assertTrue(foundFile.isFile());
        assertEquals(APPENDABLE_NEW_TMP_DIR_PATH + "FOOFILE.PNG", foundFile.getCanonicalPath());
    }
}

希望有所帮助。

答案 3 :(得分:1)

而不是返回t(文件扩展名)返回文件Object。这样你就可以确定你拥有正确的文件。如果您不想返回文件对象,请返回带扩展名的文件名。

public static File 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 f;
        }
    }catch (Exception e) {
        e.printStackTrace();
    }
    return null;
}

答案 4 :(得分:0)

NiMa Thr说,你可以用这段代码做你想要的事情:

在Windows上,如果文件存在,则无论如何都会返回true。如果文件不存在,则规范名称将相同,因此它将返回false。

在Linux上,如果文件存在不同的大小写,则规范名称将返回此不同的名称,该方法将返回true。

public static boolean fileExistsCaseInsensitive(String path) {
    try {
        File file = new File(path);
        return file.exists() || !file.getCanonicalFile().getName().equals(file.getName());
    } catch (IOException e) {
        return false;
    }
}