文件重命名失败

8
我有一个基于Eclipse插件的JFace应用程序。 一个线程通过BufferedWriter写入文件。 写入完成后,我关闭缓冲区,然后尝试重命名文件。
但有时候该文件无法重命名!
我尝试在几次重试之间添加一些Thread.Sleep(BIG_NUMBER),但没有帮助。
看起来文件被某种锁定了。(当我杀死jvm时,我可以重命名该文件)。
是否有什么方法可以解决这个问题?
操作系统:Windows XP,Windows 7 JAVA版本:1.5

你使用的是哪个操作系统? - NPE
你可以发布你正在使用的代码吗? - Diego Basch
5个回答

16

File.RenameTo() 是平台相关的,需要满足一些条件才能成功重命名文件,更好的选择是使用

Path source = currentFile.toPath();
try {
     Files.move(source, source.resolveSibling(formattedName));
} catch (IOException e) {
     e.printStackTrace();
}

在这里阅读更多

根据Java文档:

该方法的行为具有固有的平台依赖性:重命名操作可能无法将文件从一个文件系统移动到另一个文件系统,它可能不是原子性的,在目标抽象路径名已经存在的情况下,重命名操作可能会失败。应始终检查返回值以确保重命名操作成功。

请注意,Files类定义了move方法以在一种独立于平台的方式中移动或重命名文件。


在我的Windows 7上运行得非常好 - 特别是当添加REPLACE_EXISTING选项时,还可以选择ATOMIC_MOVE选项。谢谢。 - Terje Dahl

0

为了使File.renameTo()正常工作,文件需要以某种方式对外部应用程序可写。


0

我会先尝试删除,但如果删除失败(如果文件被锁定,我将无法删除它),该怎么办? - yuris

0

我们在Windows 7下遇到了UAC和意外文件权限问题。File#canWrite将返回true,即使尝试执行文件I/O也会失败。

  1. 确保您要重命名的文件实际存在
  2. 确保您尝试写入文件(或重命名文件)的位置可访问。我们向该位置写入一个简单的文本文件,在尝试进行任何进一步I/O之前检查该文件是否存在以及其内容是否正确(我们很谨慎)。

顺便说一下,canwrite 返回 true。 - yuris
“File#canWrite”会返回true,即使任何尝试执行文件I/O都将失败。我们在Windows 7下遇到了这样的情况,其中File#canWrite无法检测到UAC限制,因此该方法返回了true,但在指定位置尝试执行文件I/O时会失败(通常是静默失败)。 - MadProgrammer
我们想到的唯一解决方法是:1-编写一个临时文件并检查它是否存在以及其内容是否正确,或者2-手动复制文件。据说Java 7修复了UAC的问题,但我们还没有测试过。 - MadProgrammer

0

这对我来说很好用。重命名需要两个步骤,但不要忘记在manifest.xml中设置权限:

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_INTERNAL_STORAGE" />

public boolean RenameFile(String from, String to) { 
  to.replace(" ", ""); // clear all spaces within file name
  File oldfile = new File(from);
  File newfile = new File(to);
  File tempfile = new File(to + ".tmp"); // add extension .tmp
  oldfile.renameTo(tempfile);
  return (tempfile.renameTo(newfile));
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接