如何找出 renameTo() 失败的原因?

问题描述 投票:0回答:9

我使用的是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

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

java file file-io file-rename
9个回答
34
投票

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

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

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

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


3
投票

如果没有抛出异常(我假设您会注意到)

renameTo()
仅返回 true 或 false 来指示重命名是否成功,并且不提供任何附加信息。

由于是Windows,失败很可能表明该文件当前正在使用。发生这种情况是因为其他进程打开了它。但更有可能的是,您的进程尚未完成写入,或者您在写入完成后忘记关闭文件。

也有可能您传入了无效路径,或者为

File
构造函数提供了不存在的路径。

仅当存在安全违规 (

renameTo()

) 或传入 
SecurityException
 来重命名文件时,
null
才会引发异常。


3
投票
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


2
投票

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


2
投票

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

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

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

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


0
投票

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


0
投票

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

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


0
投票

没有人提到这一点,这只是发生在我身上,所以我想我将其发布在这里:

如果您尝试重命名的文件名无效,则重命名可能会失败。 例如,Windows 上的冒号字符。


-4
投票

文件f=新文件(文件夹+文件); 验证您是否写了正确的路径.. f.exists(); else 存在并返回 false 如果查看的话则使用 procMon 进行验证..

© www.soinside.com 2019 - 2025. All rights reserved.