Java 为什么此实用程序方法会锁定文件?

Java 为什么此实用程序方法会锁定文件?,java,file,file-io,locking,Java,File,File Io,Locking,我制作了一个简单实用的方法来读取Java中的文件。不幸的是,该方法似乎在文件运行后保持锁定状态。换句话说,即使在调用方法并将其存储在字节[]中之后,我也无法调用文件上的函数(例如.delete())。我很确定我关闭了所有的频道。知道为什么以后不能删除该文件吗?注意,当我调用.deleteOnExit()时,删除文件是有效的。我知道我可以在Java7API中使用Files.read()方法,但我想知道为什么这个方法不起作用。如有任何建议,将不胜感激 /** * Converts the file

我制作了一个简单实用的方法来读取Java中的文件。不幸的是,该方法似乎在文件运行后保持锁定状态。换句话说,即使在调用方法并将其存储在字节[]中之后,我也无法调用文件上的函数(例如.delete())。我很确定我关闭了所有的频道。知道为什么以后不能删除该文件吗?注意,当我调用.deleteOnExit()时,删除文件是有效的。我知道我可以在Java7API中使用Files.read()方法,但我想知道为什么这个方法不起作用。如有任何建议,将不胜感激

/**
 * Converts the file into a byte[]. Also Android compatible. :)
 * @param The File you want to get the byte[] from.
 * @return The byte[]
 * @throws IOException if something goes wrong in reading the file. 
 */
private byte[] mapFileIn(File infile) throws IOException{
    FileInputStream fis = null;
    FileChannel fc = null;
    try{
        fis = new FileInputStream(infile);
        fc = fis.getChannel(); // Get the file's size and then map it into memory
        int sz = (int)fc.size();
        MappedByteBuffer bb = fc.map(FileChannel.MapMode.READ_ONLY, 0, sz);
        byte[] data2 = new byte[bb.remaining()];
        bb.get(data2);
        fc.close();
        fis.close();
        return data2;
    }
    finally{//Ensures resources are closed regardless of whether the action suceeded
        try{
            fis.close();
            fc.close();
        }
        catch(Exception e){
            //Does nothing
        }
    }
}

这里的问题是内存映射的使用。另一方面,与从
FileInputStream
简单读取相比,使用内存映射来方便将整个文件读入
byte[]
似乎没有任何优势

各国的文件:

[T] 缓冲区及其表示的映射将保持有效 直到缓冲区本身被垃圾回收

映射一旦建立,就不依赖于文件通道 这是用来创造它的。特别是,关闭频道没有任何好处 对映射有效性的影响

a的文档说明了类似的内容:

映射的字节缓冲区及其表示的文件映射仍然存在 在缓冲区本身被垃圾回收之前有效


这基本上意味着,在
MappedByteBuffer
被垃圾收集之前,对该文件的引用仍然存在。根据操作系统和FS的不同,这种映射可能会阻止文件删除。

问题是,
bb
尚未被GC清除,因此仍然存在对文件的引用

内存映射文件的主要好处是,您无需将数据复制到字节[]或从字节[]复制数据即可使用它。如果在结尾需要一个字节[],我建议您直接将()读入字节[]

有一个内部方法

((DirectBuffer) bb).cleaner().clean();

释放内存映射。您必须非常确定在拨打此电话后不会使用此ByteBuffer。

我想知道这是否与您的问题有关。它说它是为Java7修复的,但是你不愿意使用Files.readAllBytes对我来说意味着你可能正在使用比7旧的东西。啊!因此,如果我添加行
bb=null所有问题都将得到解决?或者有其他方法强制垃圾收集吗?没有。这只是使它符合GC的条件。当前,一旦方法完成,它将成为合格的。GC实际发生的时间取决于JVM。是否有我可以调用的方法?例如bb.clear()?我不知道。我的建议是,如果您希望能够在此后很快地删除该文件,则应避免对其进行内存映射。