`
yonlist
  • 浏览: 85693 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

MappedByteBuffer 之文件删除问题

阅读更多

熟悉nio的朋友都知道,MappedByteBuffer大幅提高了IO效率,但却有个比较严重的问题。

看如下测试代码:

public class TestMappedByteBufferDeleteFile {
	
	File testFile;
	
	/**
	 * 创建测试文件
	 * @throws URISyntaxException 
	 * @throws IOException 
	 */
	@Before public void createFile() throws URISyntaxException, IOException {
		testFile = new File(this.getClass().getResource(".").getPath() + "/test.txt");
		if(!testFile.exists()) {
			testFile.createNewFile();
		}
		FileOutputStream fos = new FileOutputStream(testFile);
		fos.write("TestMappedByteBufferDeleteFile".getBytes());
		fos.close();
	}
	
	/**
	 * 测试使用MappedByteBuffer后直接删除文件
	 * @throws IOException 
	 */
	@Test public void testDeleteFile() throws IOException {
		map(testFile);
		testFile.delete();
		Assert.assertEquals(false, testFile.exists());
	}
	
	/**
	 * 映射文件,返回MappedByteBuffer
	 * @param file
	 * @return
	 * @throws IOException
	 */
	public MappedByteBuffer map(File file) throws IOException {
		FileInputStream in = new FileInputStream(file);   
		FileChannel ch = in.getChannel();
		MappedByteBuffer buffer = ch.map(FileChannel.MapMode.READ_ONLY, 0, file.length());
		ch.close();
		in.close();
		return buffer;
	}
}

 Junit运行,结果断言失败,文件没删除成功。

 

解决方法是加上如下代码:

/**
	 * 清理MappedByteBuffer句柄
	 * @param buffer
	 */
	public static void clean(final MappedByteBuffer buffer) {
		if (buffer == null) {
			return;
		}
		AccessController.doPrivileged(new PrivilegedAction<Object>() {
			
			public Object run() {
				try {
					Method getCleanerMethod = buffer.getClass().getMethod(
							"cleaner", new Class[0]);
					if (getCleanerMethod != null) {
						getCleanerMethod.setAccessible(true);
						Object cleaner = getCleanerMethod.invoke(buffer,
								new Object[0]);
						Method cleanMethod = cleaner.getClass().getMethod(
								"clean", new Class[0]);
						if (cleanMethod != null) {
							cleanMethod.invoke(cleaner, new Object[0]);
						}
					}
				} catch (Exception e) {
					e.printStackTrace();
				}
				return null;
			}
}

 然后将testDeleteFile() 作如下修改:

/**
	 * 测试使用MappedByteBuffer后调用clean方法后删除文件
	 * @throws IOException 
	 */
	@Test public void testDeleteFile() throws IOException {
		MappedByteBuffer buffer = map(testFile);
		clean(buffer);
		testFile.delete();
		Assert.assertEquals(false, testFile.exists());
	}

 

再运行Junit,成功!

 

之所以出现这种情况,是因为文件句柄没有被清除,还被MappedByteBuffer占据,导致外部无法操作。而要清除,得等GC收集了。

 

不知Sun何时可以提供MappedByteBuffer的unmap!

另请关注该链接:http://bugs.sun.com/view_bug.do?bug_id=4724038

分享到:
评论
1 楼 dyllove98 2011-05-26  
Here is a workaround. It uses internal JVM API to call the cleaner instead of reflection. I know it is uggly, but as long as Java provides this for us this is what we have to do.  Should be safe in a single thread.

Any comments?

ByteBuffer buf = null;
try {
    buf = allocateByteBuffer();
    doWork(buf);
} finally {
    if (buf != null && buf.isDirect()) {
        ((sun.nio.ch.DirectBuffer) buf).cleaner().clean();
    }
}

相关推荐

    读取文件数据并解析成bean实体类

    例如,Java中的`java.io`包提供了`File`类用于文件的创建、删除和重命名,而`BufferedReader`和`BufferedWriter`则用于文本文件的读写。 2. **数据解析**:数据解析是将文件内容转换为可操作结构的过程。这可能涉及...

    精选_基于JAVA实现的操作系统文件系统_源码打包

    6. **内存映射文件(Memory-Mapped File)**:Java的MappedByteBuffer允许将文件直接映射到内存,提供高性能的大数据访问。 7. **权限与访问控制**:模拟真实系统中的用户权限模型,如Unix的用户组和权限位,可以...

    文件操作工具类

    五、文件删除 删除文件通常很简单,Java中`File`类的`delete()`方法可以完成这个任务。需要注意的是,如果文件正在被其他进程使用,删除操作可能会失败,这时需要处理异常。 六、更复杂的IO操作 除了基本的文件操作...

    二级文件管理系统java

    2. **文件删除**:调用File类的`delete()`方法删除文件。需要注意的是,如果文件被其他程序占用,可能无法成功删除。 3. **文件移动**:通过`renameTo()`方法可以将文件移动到另一个位置,但这个方法不支持跨文件...

    os 课程设计 文件管理

    例如,`BufferedReader`和`PrintWriter`可以用来读写文本文件,而`FileChannel`和`MappedByteBuffer`则支持更高效的块级I/O。 6. **文件缓冲与缓存**:为了提高性能,操作系统通常会使用缓冲区来暂存文件数据。Java...

    java 开发的文件系统

    - `File`类用于文件和目录的创建、读取、删除等操作,提供文件属性的查询。 - `RandomAccessFile`支持对文件进行随机访问,适用于大文件读写。 2. **文件系统结构**: - 在Linux中,文件系统基于目录树结构,根...

    Java文件操作源码大全

    19. **内存映射文件**:`java.nio.MappedByteBuffer`提供内存映射文件功能,提升大文件处理效率。 以上只是Java文件操作的一部分知识点,实际开发中还会涉及文件权限控制、并发访问、流操作等更多内容。了解并熟练...

    文件批处理模块_java_批处理_源码

    Java文件批处理模块是一种用于高效管理大量文件的程序设计,主要应用于自动化操作,例如批量删除、移动或复制文件。在Java编程中,实现这样的功能通常涉及到对文件系统API的深入理解和利用。以下是对该模块的一些...

    android文件读写源码

    5. **文件删除与重命名** 使用`File.delete()`方法可删除文件,`File.renameTo(File dest)`用于重命名或移动文件。 6. **NIO操作** 使用`java.nio`包可以进行异步文件操作,例如`AsynchronousFileChannel`类。它...

    java文件操作总结

    Java文件操作是Java编程中必不可少的部分,它涵盖了创建、读取、写入、删除以及管理文件和目录的各种功能。在Java中,文件操作主要通过java.io包中的类和接口实现。下面将对Java文件操作进行详细的总结,并提供相关...

    B树实现的文件索引 java版

    4. **I/O操作优化**:在Java中,可以使用`RandomAccessFile`或`MappedByteBuffer`进行磁盘I/O操作,以减少磁盘访问次数。 5. **错误处理**:考虑到上传的代码可能存在问题,应包含适当的错误处理和日志记录,以便...

    java 文件处理 工具类(csdn)————程序.pdf

    当处理内存限制或性能敏感的应用时,还可以利用NIO(New I/O)的特性,如`FileChannel`和`MappedByteBuffer`进行内存映射文件操作,这允许直接在磁盘和内存之间传输数据,而无需经过CPU。 总的来说,Java提供了多种...

    JAVA_file.rar_操作 文件

    对于大文件的处理,NIO的内存映射文件(MappedByteBuffer)也是很好的选择,它可以将文件部分映射到内存,从而提高读写速度。 最后,Java的I/O流库提供了丰富的选择,如ObjectInputStream和ObjectOutputStream用于...

    java io读取文件

    - Java的`MappedByteBuffer`类允许将文件映射到内存,使得文件操作如同访问内存一样快速,适合处理大型文件。 9. **大数据量文件读取策略** - **分块读取**:对于大文件,不一次性加载到内存,而是按需分块读取。...

    基于java的操作系统课程设计-文件管理项目.zip

    7. **文件映射**:通过`MappedByteBuffer`,Java可以直接将文件映射到内存,实现高速访问。这种方式常用于大文件的处理,如日志文件或数据库文件。 8. **异步I/O**:Java 7引入了`java.nio.channels....

    Java流和文件总结(二)

    MappedByteBuffer允许将文件映射到内存,使得文件操作如同操作内存一样高效。 Java的IO库还提供了对象序列化和反序列化的功能,Serializable接口标记一个类可以被序列化,ObjectOutputStream和ObjectInputStream...

    五,Android文件IO详解

    Android提供了Java标准的`java.io`包中的类,如`File`、`FileInputStream`、`FileOutputStream`等,用于进行文件的创建、读写、删除等操作。例如,可以使用`new File(path)`创建一个`File`对象,然后通过`...

    java对大数据量文件内容的多线程读取和排序.pdf

    - 考虑使用内存映射文件(`MappedByteBuffer`)来提高读取效率,尤其是在操作系统支持大文件的情况下。 - 如果内存允许,可以采用Bloom Filter或布隆过滤器来减少排序过程中不必要的比较,降低CPU使用。 - 使用...

    java应用程序,实现对文件的读写功能—大同小异

    - **File类**:提供与文件和目录路径名字符串的转换,以及文件的创建、删除等操作。 2. **文件读取**: - **FileInputStream** 和 **BufferedReader**:用于读取字节流和字符流。通常会结合BufferedReader提高...

    java-Operation-On-Files.rar_operation

    4. **文件删除** - **File#delete()**:删除一个文件或空目录。如果文件是打开状态,可能无法删除。 - **Files#delete()**:Java 7引入的方法,提供了更丰富的异常处理机制。 5. **文件缓存操作** - **java.nio....

Global site tag (gtag.js) - Google Analytics