【问题标题】:Release Java file lock in Windows在 Windows 中释放 Java 文件锁
【发布时间】:2010-11-14 19:16:18
【问题描述】:

我在使用 java 删除 Windows 中的文件时遇到了一些问题。出于某种原因,java 一直在锁定我的文件,我不知道为什么。这是我的代码:

private byte[] getFileByteArray(File file) {
    try {
        RandomAccessFile raf = new RandomAccessFile(file, "r");
        FileChannel channel = raf.getChannel();
        try {

            ByteBuffer buffer = channel.map(FileChannel.MapMode.READ_ONLY, 0, channel.size());
            byte[] bt = new byte[buffer.remaining()];
            buffer.get(bt);
            channel.close();
            raf.close();
            file.delete();
            return bt;

        } catch (Exception ex) {
            //Logger.getLogger(ConnectionImpl.class.getName()).log(Level.SEVERE, null, ex);
            System.out.println(ex.toString());
        }

    } catch (FileNotFoundException ex) {
        Logger.getLogger(ConnectionImpl.class.getName()).log(Level.SEVERE, null, ex);
    }
    return null;
}

file.delete(),以及在资源管理器中手动尝试拒绝删除该文件,因为它仍在使用中。不过在 Linux 中一切似乎都很好。

我在某处错过了 close() 吗?我可以确认首先创建文件的方法是关闭文件,因为我可以在使用 file.delete() 运行上述代码之前删除文件

额外信息: 上面的代码是 getFileByteArray(File file) 方法的一部分,调用方式如下:

public byte[] createReport(int id) {

    Report report = new Report();
    String filename = report.CreateReport(id);
    return getFileByteArray(new File(filename));
}

谢谢

更新:我设法通过使用 ByteArrayOutputStream 将文件千字节读取到字节数组中来解决问题

正如下面提到的海报,Java 中存在一个已知错误,即 Windows 存在文件映射问题。

【问题讨论】:

  • 我在 windows 框中尝试了此代码,文件仅通过代码被删除
  • @org.life.java,所以你的意思是我上面的代码有效吗?但是在Windows资源管理器中你不能删除它??
  • 你能发布你的整个方法以及调用部分
  • 编辑主帖以包含完整方法

标签: java file-io


【解决方案1】:

这是 Windows 上 Java 中的一个已知错误,请参阅Bug #4715154

Sun 评估了该问题并通过以下说明关闭了该错误:

我们无法解决此问题。 Windows 不允许删除映射文件。这 一旦我们将垃圾收集器修复为 更迅速地释放直接缓冲区(请参阅 4469299),否则会有 我们对此无能为力。

【讨论】:

  • 好吧,我在 Win7 上尝试了 System.gc(),但它不起作用,即使是 NULLifying 和休眠。在这种情况下,我会使用 Do-Not-Use-NIO 解决方法。
  • 不使用蔚来?可以举个例子吗?
  • 按照通常的方式写信给ByteArrayOutputStream。完成后,只需调用其toByteArray() 方法即可获取byte[]
  • System.gc() 最终会起作用。我偶然发现了这个错误并编写了一个循环尝试file.delete(),调用System.gc(),然后调用Thread.sleep(2000)。大约 3 次循环后,它似乎一直在删除文件。我可能会在此处添加一个循环计数器并保留它。请注意,在删除和重新创建后映射相同的文件也会在 Windows 上导致一些问题。如果您需要这样做,我会推荐“无 NIO”路线。
  • 我只是浪费了我生命中的几个小时(如果不是几天)来追踪这个锁定问题。即使您只是使用Paths.getFile.list,您也会得到锁。如果您在 Windows 上运行,请帮自己一个忙,避免使用 java.nio。
【解决方案2】:

添加到mhalleranswer

并将sarumont的评论翻译成代码

应该/可能有效。

private static void deleteMappedFilesIfExists(Path path) throws IOException {
    while (true) {
        try {
            Files.deleteIfExists(path);
            break;
        } catch (AccessDeniedException e) {
            System.gc();
        }
        //Add delay if needed.
    }
}

【讨论】:

  • 这对我不起作用,锁/把手会保留。在 Windows 资源管理器中访问该文件会出现拒绝访问错误,直到 VM 退出,此时该目录将消失。我正在使用JDK11,也许它适用于以前的版本。
猜你喜欢
  • 2018-12-19
  • 1970-01-01
  • 1970-01-01
  • 2021-11-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-04-12
相关资源
最近更新 更多