首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何正确关闭MappedByteBuffer?

如何正确关闭MappedByteBuffer?
EN

Stack Overflow用户
提问于 2014-08-11 07:42:37
回答 4查看 4.7K关注 0票数 9

这是我正在运行的代码:

代码语言:javascript
复制
import java.io.RandomAccessFile;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;

public class Main {
    public static void main(String[] args) throws Exception {
        String filePath = "D:/temp/file";
        RandomAccessFile file = new RandomAccessFile(filePath, "rw");

        try {
            MappedByteBuffer buffer = file.getChannel().map(FileChannel.MapMode.READ_WRITE, 0, 128);

            // Do something
            buffer.putInt(4);
        } finally {
            file.close();
            System.out.println("File closed");
        }

        System.out.println("Press any key...");
        System.in.read();

        System.out.println("Finished");
    }
}

在按下键之前,我正尝试在FAR Manager中手动删除该文件。但是远远地说文件是被锁定的:

代码语言:javascript
复制
 The process cannot access the file because it is being used by another process.
                     Cannot delete the file
                         D:\temp\file
                    Object is being opened in:
 Java(TM) Platform SE binary (PID: 5768, C:\Program Files\Java\jdk1.8.0_05\bin\javaw.exe)

只有在按下键后,应用程序才会终止,而我可以删除该文件。

我的密码怎么了?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2014-08-11 09:21:03

试试这个。

代码语言:javascript
复制
public class Test
{
    public static void main(String[] args) throws Exception {
        String filePath = "D:/temp/file";
        RandomAccessFile file = new RandomAccessFile(filePath, "rw");
        FileChannel chan = file.getChannel();
        try {
            MappedByteBuffer buffer = chan.map(FileChannel.MapMode.READ_WRITE, 0, 128);

            // Do something
            buffer.putInt(4);
            buffer.force();
            Cleaner cleaner = ((sun.nio.ch.DirectBuffer) buffer).cleaner();
            if (cleaner != null) {
                cleaner.clean();
            }
        } finally {
            chan.close();
            file.close();
            System.out.println("File closed");
        }

        System.out.println("Press any key...");
        System.in.read();

        System.out.println("Finished");
    }
}
票数 7
EN

Stack Overflow用户

发布于 2018-02-16 06:07:05

@SANN3 3的答案不再适用于Java 9。在Java9中,有一个可以使用的新方法sun.misc.Unsafe.invokeCleaner。下面是一个工作代码:

代码语言:javascript
复制
MappedByteBuffer buffer = ...

// Java 9+ only:
Class<?> unsafeClass = Class.forName("sun.misc.Unsafe");
Field unsafeField = unsafeClass.getDeclaredField("theUnsafe");
unsafeField.setAccessible(true);
Object unsafe = unsafeField.get(null);
Method invokeCleaner = unsafeClass.getMethod("invokeCleaner", ByteBuffer.class);
invokeCleaner.invoke(unsafe, buffer);
票数 6
EN

Stack Overflow用户

发布于 2021-11-30 01:38:54

如果您使用的是java1.8,并且不能直接使用sun.nio.ch.DirectBuffer和Cleaner,您可以尝试:

代码语言:javascript
复制
public void clean(final ByteBuffer buffer) {
    AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
        try {
            Field field = buffer.getClass().getDeclaredField("cleaner");
            field.setAccessible(true);
            Object cleaner = field.get(buffer);

            Method cleanMethod = cleaner.getClass().getMethod("clean");
            cleanMethod.invoke(cleaner);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    });
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25238110

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档