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

关于MappedByteBuffer

    博客分类:
  • java
阅读更多
JDK1.4中加入了一个新的包:NIO(java.nio.*).这个库最大的功能就是增加了对异步套接字的支持异步套接字对服务器程序来说更具吸引力.一般同步SOCKET服务器的实现都是采用线程池来处理客户请求的,基于请求超时时间和并发线程数目的限制,如果并发处理能力能够达到上千就已经是不错了.异步服务器的能力则至少是它的数倍(有人测试一个简单的ECHO服务程序,说可以达到上万个并发,不知道是否真的能达到). SocketChannel的读写是通过一个类叫ByteBuffer(java.nio.ByteBuffer)来操作的.这个类本身的设计是不错的,比直接操作byte[]方便多了. ByteBuffer有两种模式:直接/间接.间接模式最典型(也只有这么一种)的就是HeapByteBuffer,即操作堆内存(byte[]).但是内存毕竟有限,如果我要发送一个1G的文件怎么办?不可能真的去分配1G的内存.这时就必须使用"直接"模式,即MappedByteBuffer,文件映射. MappedByteBuffer也是类似的,你可以把整个文件(不管文件有多大)看成是一个ByteBuffer.这是一个很好的设计,除了一点,令人头疼的一点. MappedByteBuffer只能通过调用FileChannel的map()取得,再没有其他方式.但是令人奇怪的是,SUN提供了map()却没有提供unmap().这样会导致什么后果呢? 举个例子,文件test.tmp是一个临时构建的文件,在业务处理(通过SocketChannel发送)完之后将不再有效.一般的做法都是这样的: (1)File file = new File("test.tmp"); FileInputStream in = new FileInputStream(file); FileChannel ch = in.getChannel(); MappedByteBuffer buf = ch.map(FileChannel.MapMode.READ_ONLY, 0, file.length()); (2)SocketChannel sch = 已经构造好了; while (buf.hasRemaining()) sch.write(buf); (3)ch.close(); in.close(); file.delete(); 上面的操作都会正常的完成,除了最后一步:文件无法删除!即使你通过资源管理器直接强制删除也不行,说"文件正在使用". 为什么会出现这种情况? 说"文件正在使用",说明文件句柄没有清零,还有在使用它的地方---就是被MappedByteBuffer占用了!尽管FileChannel,FileInputStream都已经关闭了,但是在map里还打开着一个文件句柄.但是在外部看不见也无法操作它.那么这个句柄在什么时候才会正常地关闭呢?根据JAVADOC的说明,是在垃圾收集的时候.而众所周知垃圾收集是程序根本无法控制的. 既然MappedByteBuffer是从FileChannel中map()出来的,为什么它又不提供unmap()呢?SUN自己也没有讲清楚为什么.O'Reilly的<>中说是因为"安全"的原因,但是到底unmap()会怎么不安全,作者也没有讲清楚. 在SUN的BUG库中,这个问题在02年就有人提交了BUG报告,但是SUN自己不认为是BUG,而只是一个RFE(Request For Enhancement),有待改进. 好在网上牛人多.在BUG报告(http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4724038)中,有网友提出了一个解决的办法(具体参看上面的URL),可行,至少我在WINDOWS2000下测试是可以的.唯一的不足是并不是每次都能马上生效(文件彻底被删除),有的时候要延迟一会再试. 再抱怨两句.对于网友们的BUG报告,SUN似乎不怎么重视.粗看一下上面的BUG报告,会发现居然上世纪90年代的报告还赫然在列.有兴趣的朋友不妨仔细研究研究. 还有一点忘了说了.ByteBuffer是无法派生的.因为这个抽象类中定义了几个包抽象方法,即实现类只能位于java.nio包中.本来自己实现MappedByteBuffer也不难,只是效率比SUN实现的肯定要低一些.毕竟后者是可以直接与操作系统打交道的.而要是自己实现的化,只能通过一个中间的堆缓冲区进行过渡. 补充回答: 复制内容到剪贴板代码:
import java.nio.*;
import java.nio.channel.*;
import java.io.*;
public static void copy(File source, File dest) throws IOException {
FileChannel in = null, out = null;
try {
in = new FileInputStream(source).getChannel();
out = new FileOutputStream(dest).getChannel();

long size = in.size();
MappedByteBuffer buf = in.map(FileChannel.MapMode.READ_ONLY, 0, size);

out.write(buf);
if (in != null) in.close();
if (out != null) out.close();
}
}
转http://wenwen.soso.com/z/q132821597.htm
分享到:
评论

相关推荐

    深入浅出MappedByteBuffer.pdf

    《深入浅出MappedByteBuffer》这篇文章主要探讨了Java NIO中MappedByteBuffer这一高效处理大文件的机制,以及与其相关的计算机内存管理概念。首先,我们来详细理解一下这些知识点。 内存管理是计算机系统的重要组成...

    Bug ID 4724038 (fs) Add unmap method to MappedByteBuffer

    Bug ID 4724038 (fs) Add unmap method to MappedByteBuffer

    文件分割和合并(您的文件大的不能传输怎么办?)

    本人初学c++,写了一个小软件,能把大文件分割问小文件,然后可以统国网络传输,到了网络另一端,再用此软件拼接! 希望用过的人能提宝贵意见! 13521825644 qq 362192302

    【IT十八掌徐培成】Java基础第27天-01.MappedMemoryBuffer-文件内存映射缓冲区.zip

    Java中的MappedByteBuffer是Java NIO(New Input/Output)库的一部分,它提供了一种高效的方式来访问和操作大文件。在标题和描述中提到的“文件内存映射缓冲区”是Java处理大文件的一种高级技术,它允许将文件直接...

    commons-mmf.rar_java nio_java共享内存_共享内存

    在Java中,可以通过`java.nio.MappedByteBuffer`类来实现共享内存功能,这被称为内存映射文件(Memory-Mapped File,MMF)。 `MappedByteBuffer`是NIO中的一种特殊缓冲区,它将文件的一部分映射到内存中,使得文件...

    java读取大文件

    为了有效地读取大文件,可以使用缓冲区(Buffer)和内存映射文件(MappedByteBuffer)技术。下面将详细解释如何使用这些技术以及代码中的关键部分。 1. **缓冲区(Buffer)**: Java中的缓冲区是用于提高数据读写...

    关于断点续传的相关资料,包含源代码

    MappedByteBuffer buffer = remoteChannel.map(FileChannel.MapMode.READ_ONLY, remoteChannel.position(), blockSize); if (buffer.limit() == 0) break; localChannel.write(buffer); } // 关闭文件通道 ...

    java8源码-netty-learn:这是一个用于netty学习的工程

    MappedByteBuffer DirectByteBuffer HeapByteBuffer ShortBuffer IntBuffer LongBuffer FloatBuffer DoubleBuffer CharBuffer Selector选择器 Selector的作用就是配合一个线程来管理多个channel,获取这些channel上...

    Java NIO 应用使用内存映射文件实现进程间通信

    在Java NIO中,内存映射文件(MappedByteBuffer)是一个重要的特性,它允许将文件直接映射到内存中,以便于快速访问和修改文件内容。这一特性不仅提高了读写效率,而且还能用于进程间通信(IPC)。 内存映射文件的...

    java读取超大文本文件

    对于需要随机访问或文件特别大的情况,推荐使用`RandomAccessFile`和`FileChannel`的组合,特别是利用`MappedByteBuffer`进行内存映射文件读取。这种方式能够显著提高文件的读取速度,因为数据直接从磁盘映射到内存...

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

    在IT行业中,文件数据的处理是一项常见的任务,特别是在数据交换和存储时。"读取文件数据并解析成bean实体类"这一主题涉及到的核心知识点主要包括文件操作、数据解析以及对象映射。下面将详细阐述这些概念及其应用。...

    文件高速传输读写 客户端服务端

    本主题聚焦于Java平台下如何实现高效的文件操作,特别是利用内存映射(MappedByteBuffer)进行读写和通过网络进行文件传输。以下是相关的知识点详解: 1. **内存映射文件(MappedByteBuffer)**: 内存映射文件是...

    java 中Buffer源码的分析

    另外,虽然 MappedByteBuffer 在逻辑上应该是 DirectByteBuffer 的子类,而且 MappedByteBuffer 的内存的 GC 和直接内存的 GC 类似(和堆 GC 不同),但是分配的 MappedByteBuffer 的大小不受 -XX:...

    j2se项目源码及介绍_last指令

    函数原型 private MappedByteBuffer mappedFile2Buffer(File f) throws Exception 函数说明 把日志文件映射成内存缓冲 参数说明 @param File f日志文件 返回说明 @return MappedByteBuffer 内存映射缓冲。 异常说明 ...

    NIO按行读取数据

    - **MappedByteBuffer**:文件映射缓冲区,它允许将文件的一部分直接映射到内存,从而提供快速的文件访问。 2. **按行读取的实现**: - 类`NioReader`初始化时,创建了一个`FileInputStream`和`FileChannel`对象...

    Java中用内存映射处理大文件的实现代码

    FileChannel提供了map()方法,可以将文件的一部分或全部映射到Java虚拟机的内存中,形成一个MappedByteBuffer对象。这样,对MappedByteBuffer的操作实际上就是对文件的直接操作,无需频繁地进行磁盘I/O,大大提高了...

    Java内存映射 大文件轻松处理

    MappedByteBuffer mappedByteBuffer = fileChannel.map(MapMode.READ_ONLY, 0, fileChannel.size()); CharBuffer charBuffer = Charset.forName("UTF-8").decode(mappedByteBuffer); System.out.println...

    mmfinvoker:简单的进程间 java 请求-响应库

    mmfinvoker是一个专注于进程间通信(IPC)的Java库,利用Java的NIO(Non-blocking Input/Output)特性,特别是MappedByteBuffer,来实现在内存映射文件上的高效请求-响应机制。在Java中,内存映射文件是一种将文件...

    Java IO流总结

    在Java NIO(New IO)库中,引入了一种更高效的数据处理方式——MappedByteBuffer,对应于描述中的"mmap"。内存映射文件(Memory-Mapped File)是一种将文件直接映射到进程的虚拟内存空间的技术,使得可以直接通过...

    简要分析Java多进程编程的并发控制

    对于内存共享,Java在JDK 1.4及更高版本中引入了`MappedByteBuffer`类,它允许我们将文件映射到内存,从而实现共享内存。`MappedByteBuffer`是NIO(非阻塞I/O)的一部分,它通过文件通道`FileChannel`与磁盘文件交互...

Global site tag (gtag.js) - Google Analytics