【问题标题】:How to find out why renameTo() failed?如何找出 renameTo() 失败的原因?
【发布时间】:2010-11-22 11:04:47
【问题描述】:

我正在使用 WinXP。我使用 java 生成文件列表。文件一开始会创建为abc.txt.temp,生成完成后重命名为abc.txt。

但是,当我生成文件时,某些文件无法重命名。它是随机发生的。

有没有办法找出失败的原因?

int maxRetries = 60;
logger.debug("retry");
while (maxRetries-- > 0)
{
    if (isSuccess = file.renameTo(file2))
    {
        break;
    }
    try
    {
        logger.debug("retry " + maxRetries);
        Thread.sleep(1000);
    }
    catch (InterruptedException e)
    {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }   
}

//file.renameTo(file2);
Thread.currentThread().getThreadGroup().getParent().list();

结果:

[DEBUG][2009-08-25 08:57:52,386] - retry 1
[DEBUG][2009-08-25 08:57:53,386] - retry 0
java.lang.ThreadGroup[name=system,maxpri=10]
    Thread[Reference Handler,10,system]
    Thread[Finalizer,8,system]
    Thread[Signal Dispatcher,9,system]
    Thread[Attach Listener,5,system]
    java.lang.ThreadGroup[name=main,maxpri=10]
        Thread[main,5,main]
        Thread[log4j mail appender,5,main]
[DEBUG][2009-08-25 08:57:54,386] - isSuccess:false

我想知道一个系统的方法来找出原因。谢谢。

【问题讨论】:

  • 您是否捕捉到任何抛出的异常?
  • 没有。一点也不例外。它只返回 false。
  • 你能详细说明你在这里使用多线程吗?这听起来像是一种竞争条件,但如果没有更多信息,我无法开始猜测实际的故障点。
  • 我没有在我的程序中创建任何新线程。我只是检查是否在我不知情的情况下创建了任何线程。

标签: java file file-io file-rename


【解决方案1】:

我在 Mac 上也看到了同样的情况。我有一个在单个线程中创建 163,000 个文件的进程。它跳过创建任何已经存在的文件。为避免部分文件问题,在写入文件时,它会写入一个临时文件(.../dir/tmp.filename),然后将其重命名(.../dir/filename)。

我运行了一次(从 IntelliJ 内部),然后运行窗口消失了,这很奇怪。我重新启动 IntelliJ 并再次运行它,并开始在我的文件重命名的一堆(但不是全部)上出现错误。事实证明,我之前运行的 java 进程仍在运行,即使 IntelliJ(它启动了它)已经退出。所以我有两个进程在寻找相同文件的存在并相互踩踏。

【讨论】:

    【解决方案2】:

    也有可能您没有重命名文件,因为您没有足够的权限。在 Unix 上,这很简单。在 Win10 上,嗯...参见例如https://www.sevenforums.com/tutorials/1911-take-ownership-shortcut.html

    【讨论】:

      【解决方案3】:

      renameTo 失败的三个主要原因(对于 Android,但您也可能会发现这很有用)!

      1) 如果您将文件夹从a 地移动到b 地,则目标文件夹可能是一个文件!将destinationFolder.mkdirs() 设为文件!

      2) 目标文件夹可能已经存在!删除destinationFolder,以便您可以使用renameTo 将旧文件移动到新位置

      3) 将内部存储移动到外部存储需要权限,因为读取和写入 SD 卡需要权限!

      【讨论】:

      • 我通过谷歌找到了这个问题,#2 是我的问题。感谢您的帮助!
      • "将 destinationFolder.mkdirs() 设为文件!"嗯?
      【解决方案4】:
      File o=new File("d:/old.txt");
      File n=new File("d:/new.txt");
      n.delete();
      o.renameTo(n);
      

      n.delete():如果存在,我们需要删除文件(new.txt)。

      o.rename(n) :使文件(old.txt)重命名为new.txt

      【讨论】:

      • 我就是这样做的,但仍然从重命名中得到错误的返回。该文件已关闭,没有其他任何东西。视窗。只是... Windows。
      【解决方案5】:

      文件 f=新文件(文件夹+文件); 验证您是否编写了正确的路径.. f.存在(); else 是存在的,如果被查看则返回 false 验证与 procMon..

      【讨论】:

        【解决方案6】:

        我遇到了类似的问题,但这是与 unix 相关的。
        重命名随机失败。我重新启动了该过程 3 到 4 次,终于成功了。
        仅供参考,该文件是由同一进程创建的,并且同一进程将其重命名..

        【讨论】:

          【解决方案7】:

          重命名失败的原因可能是文件仍然处于打开状态。即使您正在关闭文件,它也可能因为(例如)而保持打开状态:

          1. 文件句柄由进程的子进程继承
          2. 防病毒程序正在扫描文件以查找病毒,因此已将其打开
          3. 索引器(例如 Google 桌面或 Windows 索引服务)已打开文件

          要帮助找出使文件保持打开状态的原因,请使用 FileMonHandle 等工具。

          更新:如果文件仅在很短的时间内保持打开状态(防病毒扫描就是这种情况),Unlocker 等工具可能无济于事。但是,如果 javaw.exe 显示文件已打开,那就是您的问题。

          【讨论】:

          • 我正在使用解锁器。它只显示“javaw.exe”作为唯一的储物柜。 :(
          • 我认为像杀毒软件和索引器这样的扫描应用程序不应该能够保存文件并防止它被更改或重命名...... WinXP中真的是这种情况吗?跨度>
          • 他们不会长时间保持文件打开,但通常会监视文件更改并在文件更新后进行扫描。如果你写入一个文件,关闭它然后尝试重命名它,文件可以在那个时候仍然保持打开状态(虽然不会很长时间)。
          【解决方案8】:

          如果没有抛出异常(我假设你会注意到)renameTo() 仅返回 true 或 false 以指示重命名是否成功并且不提供任何其他信息。

          由于是 Windows,因此故障很可能表明该文件当前正在使用中。之所以会发生这种情况,是因为其他一些进程已将其打开。但更有可能的是,您的进程要么没有完成写入,要么在完成写入后忘记关闭文件。

          也有可能您传入了无效的路径,或者给File 构造函数提供了不存在的路径。

          renameTo() 只会在存在安全违规 (SecurityException) 或传入 null 以重命名文件时抛出异常。

          【讨论】:

          • 我知道它返回 false,但它不提供失败的原因。我已经关闭了所有 outputStream.close() 并将其设置为 null。但它仍然随机失败。假设我生成了10个文件,file0.tmp ... file9.tmp,可能是file5.tmp无法更改为file5.txt。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2011-09-11
          • 2017-05-15
          • 2016-08-21
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-08-23
          相关资源
          最近更新 更多