【问题标题】:Case sensitive file extension and existence checking区分大小写的文件扩展名和存在检查
【发布时间】:2012-11-17 05:13:58
【问题描述】:

我需要检查一个文件是否存在。这可以通过File#exists() 方法完成。但是这种存在性检查是区分大小写的。我的意思是,如果我在代码中有一个文件名 some_image_file.jpg 但如果文件在物理上是 some_image_file.JPG 那么这个方法说该文件不存在。如何检查扩展名不区分大小写的文件是否存在并获取实际文件名?

在我的场景中,我有一个 excel 文件。每行包含文件的元数据和文件名。在某些情况下我只有文件名或其他情况下我可以有完整路径。我将一行表示为一个文档。

这些文件被放置在服务器中。我的工作是

  • 逐行读取excel文件,列出所有文档。
  • 取出文件名或文件路径。
  • 创建文件的完整路径。
  • 检查文件是否存在。
  • 验证文档中提供的其他元数据/信息。
  • 上传文件。

如果文件不存在或某些元数据无效,我的应用程序会抛出异常。

excel文件是客户写的,有些文件名写错了,我的意思是如果文件物理上有小写扩展名,他们把扩展名写成大写,反之亦然。

我在 unix 服务器上运行应用程序。

由于文件扩展名不匹配,所以File#exists() 给出错误,最终我的代码抛出异常。

放置文件的文件夹可以有30000个或更多的文件。

我想要的是

  • 获取文件的完整路径。
  • 检查文件是否存在。
  • 如果不存在则
  • 通过转换扩展名的大小写来检查文件是否存在。
  • 如果在大小写转换后不存在则抛出异常。
  • 如果存在,则返回实际文件名或文件路径。

如果文件名有.jpg之类的文件扩展名,不知道该怎么办!我应该通过改变大小写来排列它来检查它吗?

【问题讨论】:

  • 只是为了检查 - 您在 Windows 上运行,对吗? (在区分大小写的文件系统上,这个问题没有多大意义。)我自己刚刚尝试使用File.exists,故意指定错误的文件名大小写,它工作正常......
  • @JonSkeet 我在 UNIX 中运行。
  • 好吧,就File.exists 的行为而言,这更有意义 - 但就您为什么要这样做而言意义不大。你从哪里得到文件名?您可以依赖哪些信息?
  • @JonSkeet 我通过解析 excel 文件来获取文件名。在我的要求中,我需要读取 excel 文件,获取文件文件名和其他元数据,检查文件是否存在并将文件与内容服务器中的元数据一起上传。在某些情况下,文件实际显示为 .JPG,但在 excel 中为 .jpg,反之亦然。因此,当我从 excel 文件中读取文件名为 .jpg 并且该文件实际上具有 .JPG 并且我正在检查该文件是否存在时,我得到了错误。
  • 那么你读到的文件名是绝对的吗?你怎么知道要查看哪个目录? (如果您使用所有此类信息更新问题,这将非常有帮助 - 如果我们不得不一个接一个地询问信息,这将更加难以帮助您。)

标签: java file case-sensitive case-insensitive file-exists


【解决方案1】:

规范名称返回区分大小写的名称。如果它返回的字符串与您要查找的文件的名称不同,则该文件以不同的大小写存在。

所以,测试文件是否存在或者它的规范名称是否不同

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

【讨论】:

    【解决方案2】:

    这样我就解决了问题:

    public String getActualFilePath() {
        File givenFile = new File(filePath);
        File directory = givenFile.getParentFile();
    
        if(directory == null || !directory.isDirectory()) {
            return filePath;
        }
    
    
        File[] files = directory.listFiles();
        Map<String, String> fileMap = new HashMap<String, String>();
    
        for(File file : files) {                        
            if(file.isDirectory()){
                continue;
            }
    
            String absolutePath = file.getAbsolutePath();
            fileMap.put(absolutePath, StringUtils.upperCase(absolutePath));
        }
    
        int noOfOcc = 0;
        String actualFilePath = "";
    
        for(Entry<String, String> entry : fileMap.entrySet()) {
            if(filePath.toUpperCase().equals(entry.getValue())) {
                actualFilePath = entry.getKey();
                noOfOcc++;
            }
        }
    
        if(noOfOcc == 1) {
            return actualFilePath;
        }
    
        return filePath;
    }
    

    这里filePath是文件的完整路径。

    【讨论】:

      【解决方案3】:

      您可以使用

      获取文件夹中的文件名
      File.list() 
      

      并通过

      检查名称
      equalsIgnoreCase()
      

      或者试试http://commons.apache.org/io/ 并使用

      FileNameUtils.directoryContains(final String canonicalParent, final String canonicalChild)
      

      【讨论】:

      • 谢谢。但我没有文件夹的名称,文件可能不存在。
      • 您的意思是,您正在检查完整的文件名,类似于“D:\test\base\some_image_file.JPEG”?
      • 是的,类似的。但在这种情况下,可以通过少量字符串操作来提取文件夹名称。但该文件夹可以有 30000 个或更多文件。所以在这种情况下,对于每个文件,我需要列出所有这些文件!
      • 你也可以试试commons.apache.org/io 并使用 FileNameUtils.directoryContains(final String canonicalParent, final String canonicalChild)
      猜你喜欢
      • 1970-01-01
      • 2016-04-03
      • 2018-10-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-03
      • 1970-01-01
      相关资源
      最近更新 更多