【问题标题】:File.exists() returns false when file exists当文件存在时 File.exists() 返回 false
【发布时间】:2010-10-29 12:39:50
【问题描述】:

我遇到了一个错误,我似乎找不到任何背后的逻辑。我有这个 File 对象,它是这样创建的:

File file = new File("utilities/data/someTextFile.txt");

然后我执行file.exists(),它返回false (!?)。如果找不到该文件,我会将f.getAbsolutePath() 记录到一个文件中。当我查看路径时,似乎还可以。我可以将完整的路径复制粘贴到 Windows 的“运行”窗口中,文件可以正常打开。

该文件始终存在,在我的应用程序运行期间不会被删除或更改。它位于本地机器上。

这似乎只在某些情况下发生。我可以随时重现故障,但我确信文件对象的路径不会因我为重现故障而采取的操作而改变。

什么会导致 file.exists() 返回 false?这是否与权限或文件锁定等有关?

【问题讨论】:

  • 那么,即使exists()返回false,是否可以从文件中读取?
  • 是的,即使 exists() 返回 false,我也可以从文件中读取。
  • 重现故障究竟需要什么?
  • 这是在一个应用程序内部,它调用用 matlab 编写的函数并编译到 java 应用程序中。似乎改变“当前目录”的matlab函数导致问题出现。我在创建文件对象时使用的是绝对路径,所以这应该不是问题 - 但它似乎是。我当然验证了文件对象的绝对路径,是正确的(和matlab函数改变当前目录之前一样)。
  • 您是否有机会使用远程目录(例如 NFS 挂载)?

标签: java file-io


【解决方案1】:

我在 Windows 7 上看到以下情况:

file.exists() == false
file.getAbsoluteFile().exists() == true

有问题的文件是“var\log”,绝对路径确实引用了普通子目录(不是虚拟存储)中的现有文件。这是从 IDE 中看到的。

【讨论】:

  • 我刚刚想通了:bugs.sun.com/bugdatabase/view_bug.do;:YfiG?bug_id=4483097 显然,对文件运行的操作是针对当前目录解析的,而 getAbsolutePath 是针对 user.dir 解析的。如果这两个路径不匹配,则会得到相互冲突的结果。恶魔般的!
  • 我遇到了完全相同的问题,我尝试使用这两种方法来检查文件是否存在,但我仍然只在 Windows 7 上得到错误!有什么想法吗?
  • @Odelya:您使用的是什么 IDE?您的 -Duser.dir 设置为什么?我的问题是由于将 -Duser.dir 设置为与当前工作目录不同的目录引起的。
  • 对于任何从事动态 Web 项目的人,使用 file.exists() 会抛出异常,使用 file.getAbsoluteFile().exists() 检查 WEB-INF 目录中的文件(一般提示,不是特定于 Windows 7)。
  • 考虑为此答案和 cmets 创建单独的 QA
【解决方案2】:

似乎在 Java 中指定路径的方式有所不同。

例如,如果文件路径被指定为file:/C:/DEV/test.txt那么

File f = new File(filename);
f.exists();

将返回false。该路径可能在资源管理器或浏览器中有效,但它是 URL 而不是绝对文件路径。

但是另一方面,如果文件路径被指定为C:/DEV/test.txt 那么

File f = new File(filename);
f.exists();

将返回true,因为路径不是 URL,而是绝对路径。

Spring Framework 正是 ResourceUtils.getFile(filename) 所做的 - 其中名称可以是 URL 或绝对文件路径。

【讨论】:

  • 我不希望 file:/C:/DEV/test.txt 用作路径名。它是一个 URL 而不是路径名。虽然有些人犯了这个错误,但没有证据表明 OP 有......
【解决方案3】:

如果进程没有权限判断文件是否存在,它将返回 false。可以打开一个文件,但不能通过常规方法判断它是否存在。

【讨论】:

  • 有趣。你能扩展一下吗?您想到了哪些特定权限?
  • 这里可以通过 java.nio.file.AccessDeniedException 阻止能力来获取文件/目录的存在。例如,如果您在 FAR 或其他文件资源管理器中保持打开的 dir,然后删除包含所有嵌套文件的 dir 并检查此 dir 的存在,那么您可以获得 AccessDeniedException(扩展 IOException)以获取为您保留的临时文件。在这种情况下,Files.exists 为 IOException 返回 false。
【解决方案4】:

以上答案对我的情况没有帮助。如上所述,我有:

file.exists() => false
file.getAbsoluteFile().exists => true

造成这种情况的根本原因是 Windows 7 机器所有者修改了 CMD 的注册表,以便它会自动运行命令以在特定目录中启动以使用 Python。此修改削弱了 Java 1.6 代码,该代码显然在 Windows 上使用 CMD 进行某些文件操作,例如 exists()。从注册表中消除自动运行解决了这个问题。

【讨论】:

  • 3.5 年后,我遇到了同样的问题。每次启动 cmd.com 时,我都会设置一个自动运行脚本来配置环境变量。它甚至没有改变当前目录——只是一些 doskey 宏和一些环境变量。我删除了自动运行,只是手动运行文件中的命令,突然 File.exists() 工作正常。
  • OMG,它确实有效(两者都有效),我只是在愚蠢地检查错误的文件并遇到了这个问题,以找出为什么它们都不适合我:) 顺便说一句,似乎在exists 之后的第二行中缺少() ;)
【解决方案5】:

当[“隐藏已知文件类型的扩展名”时。选中Windows在[Explorer] / [运行Windows]中键入“t.txt”时打开“t.txt.txt”,但以编程方式键入“t.txt”。

【讨论】:

  • 我遇到了这个问题,问题是我在 C:\test 中创建了一个名为“testFile.txt”的 txt 文件。我使用路径 C:\test\testFile.txt 引用了这个文件,但它不起作用。这是因为该文件实际上已保存为 testFile.txt.txt,因此对上述解决方案投了赞成票(旧问题,但没有接受的答案!)
  • 上帝的 Windows 太烂了。
【解决方案6】:

显然有许多可能的原因,之前的答案很好地记录了它们,但这是我在一个特定情况下解决这个问题的方法:

我的一个学生遇到了这个问题,我差点把头发扯下来试图解决这个问题。事实证明该文件不存在,即使它看起来确实存在。问题在于 Windows 7 被配置为“隐藏已知文件类型的文件扩展名”。这意味着如果文件看起来名称为“data.txt”,它的实际文件名是“data.txt.txt”。

希望这可以帮助其他人节省一些头发。

【讨论】:

  • 我认为这不是我的问题。正如我的问题中提到的:“我可以将完整路径复制粘贴到 Windows 中的“运行”窗口中,并且文件可以正常打开。”,这意味着该文件确实存在。
【解决方案7】:

如果您不想在每次必须调用方法时都处理 getAbsoluteFile() 调用,则最好使用绝对路径创建文件实例。这应该可以解决问题:

File file = new File("utilities/data/someTextFile.txt").getAbsoluteFile();

我建议用 try-catch 块包围它,顺便说一句。

【讨论】:

    【解决方案8】:

    new File 命令只是使用给定的路径名​​创建一个文件的实例。它实际上并没有在硬盘驱动器上创建文件。

    如果你说

    File file = new File ("path");
    file.exists() 
    

    仅当存在具有相同路径的现有文件时,才能返回 true。如果您打算检查第一行中声明的同一文件,则可能需要以这种方式使用它。

    File file = new File ("path");
    file.createNewFile();
    file.exists();
    

    现在这将返回 true。

    【讨论】:

    • 小解释:每次使用 new 关键字调用构造函数都会创建一个 Object - 在这种情况下,与 Class 描述的 Object 相同,名称为 File !所以不是 File != 描述符的实例 :)
    【解决方案9】:

    为了概括问题,将 URL/URI 转换为本地路径时会出现问题。

    Example: URL url = file:/D:/code%20repo%20sample/sample.txt
    
    // To remove url reference
    String localPath = url.getPath();  
    > /D:/code%20repo%20sample/sample.txt
    
    // Decoding reserved characters in url from hexadecimal to character
    URLDecoder.decode(localPath, StandardCharsets.UTF_8.toString()); 
    > /D:/code repo sample/sample.txt
    

    希望这会有所帮助。

    【讨论】:

      【解决方案10】:

      就我而言

      文件保存在

      filepath = Environment.getExternalStorageDirectory().getAbsolutePath()+ "/VRSI/Audio/"+encrypted_filename+".mp3";
      

      它存储在

      /storage/emulated/0/VRSI/Audio/82B0999F16251F0DFE849F380D6AAEEA.mp3
      

      当我得到文件路径的时候是

      /storage/emulated/0/Android/data/com.numerotec.vrsi/files/VRSI/Audio/AF7DC6C0C0B3EF3529EC70DAEF2324E0.mp3
      

      所以我将字符串“Android/data/com.numerotec.vrsi/files/”替换为空

      之后

      if (file.getAbsoluteFile().exists())
      {
          // write your code
      } 
      

      工作正常

      【讨论】:

      • 对不起,我不知道如何在stackoverflow中格式化代码
      • 感谢格式化代码。谢谢先生
      • 我有同样的问题,但我绝对肯定这在 IDE 中有效,但从我们的独立应用程序运行时不知何故。
      • getAbsoluteFile() 有效,但现在我担心这在我期望相对路径有效的类似情况下会失败......
      【解决方案11】:

      大家的反应很好。我发现这似乎是 Java 访问 Windows 上的根 C: 目录的问题。任何其他目录都应该没问题,但出于某种原因,特别提到 C:\C:C:/ 可能会出错。我已经解决了这个非常相似的问题,方法是将提及 new File("C:"); 并用新的 File(System.getProperty("file.separator")); 替换它,或者你应该能够硬编码“\”而不是说“c:”作为你的文件目录,它可能会解决。不优雅,但在这个项目上为我完成了工作。

      我希望它有所帮助。可能不是正确的解决方案,但至少它对我有用。我在JRE 1.6, Win 7。干杯!

      尊敬的,

      @Carpenter1010

      【讨论】:

        【解决方案12】:

        如果失败的情况涉及以其他用户身份运行它,并且您使用的是 Windows Vista/Windows 7,则可能是由 VirtualStore 引起的,这是一种 Windows 允许非特权用户“写入”通常无法实现的机制。但是,更改存储在“%USERPROFILE%\AppData\Local\VirtualStore\”中,每个用户帐户都是私有的。

        【讨论】:

        • 我在 windows xp x86 上运行
        【解决方案13】:

        当上面没有任何东西对我有用时,我尝试了

        filePath = filePath.trim();
        

        这将清除您的字符串中任何不需要的字符

        【讨论】:

          【解决方案14】:

          FWIW,还有另一个地方发生这种情况。

          File("") 是当前目录的名称。 File("").exists() 通常会返回 falseFile(("").getAbsoluteFile().exists() 技巧有效,将返回 true(假设当前目录存在......)

          【讨论】:

            【解决方案15】:

            我最近遇到了同样的问题。我所做的是卸载Netbeans,从C盘删除netbeans文件夹,程序文件,更新,programData,几乎无处不在。然后重新安装。现在工作正常。 在进行上述操作之前,不要忘记备份 netbeans 项目文件夹。

            希望对你有帮助。

            【讨论】:

              【解决方案16】:

              对于某些 IDE(可能是)或某些操作系统(例如:窗口),默认情况下它们没有文件的写入权限。所以如果你尝试做 file.exists() 它会告诉你错误。为了解决这个问题,请执行以下操作

              如果 File 的 ref 变量为 f,例如:File f = new File("path");

              所以为了让它工作,用鼠标选择 f 然后进入搜索菜单 > 写入权限 > 工作区。希望它会奏效。

              【讨论】:

                【解决方案17】:

                我认为您应该改用反斜杠,如下所示:

                文件 file = new File("C:\\User\\utilities\\data\\someTextFile.txt"); (两个反斜杠,不是错字)

                应该能解决问题:)

                【讨论】:

                • 我认为这个问题更多地与绝对路径与相对路径有关。即使是 Windows 路径,斜线在 Java 中也是有效的。
                猜你喜欢
                • 2011-07-23
                • 2012-10-22
                • 2015-09-21
                • 2017-08-16
                • 1970-01-01
                • 1970-01-01
                • 2015-05-05
                • 2019-12-30
                • 2015-10-20
                相关资源
                最近更新 更多