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