下载安卓APP箭头
箭头给我发消息

客服QQ:3315713922

详谈在Java中的RandomAccessFile用法教程

作者:课课家教育     来源: http://www.kokojia.com点击数:1795发布时间: 2016-05-07 16:48:10

标签: AccessJava多线程

大神带你学编程,欢迎选课

    在介绍RandomAccessFile的用法前,我们先来学习一下java,java是一种编程语言,可以撰写跨平台应用程序的面对对象的程序设计语言,其技术上具有肥城卓越的通用性、高效性、平台移植性和安全性,它应用广泛,在PC上、数据中心,游行控制台、科学超级计算机、移动电话和互联网,而且它同时拥有全球最大的专业开发社群。本文将会介绍java中RandomAccessFile的用法。

详谈在Java中的RandomAccessFile用法教程_Access_Java_多线程_课课家

  RandomAccessFile

  看到RandomAccessFile的时候,有没有觉得自己的英语水平又提高了一个档次了呢?哈哈,现在先介绍一下RandomAccessFile,RandomAccessFile是用来访问那些保存数据记录的文件的,你就可以用seek( )方法来访问记录,并进行读写了。这些记录的大小不必相同;但是其大小和位置必须是可知的。但是该类仅限于操作文件。

  但是RandomAccessFile是不属于InputStream和OutputStream类系的。它实际上是,除了实现DataInput和DataOutput接口之外(DataInputStream和DataOutputStream也实现了这两个接口),它和这两个类是没有相关性的,甚至是不使用InputStream和OutputStream类中已经存在的任何功能;而RandomAccessFile它是一个完全独立的类,而它本身使用所有方法(绝大多数都只属于它自己)都是从零开始写的。这可能是因为RandomAccessFile能在文件里面前后移动,所以它的行为与其它的I/O类有些根本性的不同。总而言之,它是一个直接继承Object的,独立的类。

  基本上,RandomAccessFile的工作方式是,把DataInputStream和DataOutputStream结合起来,然后再加上它自己的一些方法,比如定位用的getFilePointer( ),再在文件里移动用的seek( ),以及判断文件大小的length( )、skipBytes()跳过多少字节数。此外,它的构造函数还要一个表示以只读方式("r"),还是以读写方式("rw")打开文件的参数 (和C的fopen( )一模一样)。它不支持只写文件。

  很多方法中也就只有RandomAccessFile才有seek搜寻方法,而这个方法也只适用于文件。BufferedInputStream有一个mark( )方法,你可以用这个方法来设定标记(把结果保存在一个内部变量里),然后再调用reset( )返回这个位置,但是它的功能太弱了,而且也不怎么实用。

  RandomAccessFile的绝大多数功能都已经被JDK 1.4的nio的"内存映射文件(memory-mapped files)"给取代了,但不是全部被取代,所以在使用时你需要考虑一下是否该用"内存映射文件"来代替RandomAccessFile了。

RandomAccessFile

  内存映射文件

      内存映射文件是由一个文件到一块内存的映射。它与虚拟内存有些类似,都是通过内存映射文件可以保留一个地址空间的区域,而且它同时是将物理存储器提交给此区域,然后内存文件映射的物理存储器来自一个已经存在于磁盘上的文件,而且在对该文件进行操作之前必须首先对文件进行映射。内存映射文件是能够让你创建和修改那些占内存大而无法放入内存的文件。而有了内存映射文件,你就可以认为文件已经全部读进了内存,然后把它当成一个非常大的数组来访问。这种解决办法能大大简化修改文件的代码。

  fileChannel.map(FileChannel.MapMode mode, long position, long size)是将此通道的文件区域直接映射到内存中。但是需要注意的是,你必须指要明,它是从文件的映射的开始位置,范围;那换言之,它还可以映射一个大文件的某个小片断。

  MappedByteBuffer 只是一种特殊的 ByteBuffer ,即是ByteBuffer的子类,因此它具备了ByteBuffer的所有方法,而MappedByteBuffer 可以将文件直接映射到内存,但新添了force()将缓冲区的内容强制刷新到存储设备中去、load()将存储设备中的数据加载到内存中、isLoaded()位置内存中的数据是否与存储设置上同步。这里只简单地演示了一下put()和get()方法,除此之外,你还可以使用asCharBuffer( )之类的方法得到相应基本类型数据的缓冲视图后,可以方便的读写基本类型数据。

MappedByteBuffer 子类

  尽管映射需要用到FileOutputStream,但是映射文件中的所有输出都是必须使用RandomAccessFile,但如果只需要读时可以使用FileInputStream,写映射文件时一定要使用随机访问文件,这可能是因为写时需要读。

  在这个过程中该程序创建了一个128Mb的文件,如果一次性读到内存的话可能会导致内存溢出,但这里访问好像只是一瞬间的事,因为这是真正调入内存的只是其中的一小部分,其余部分则被放在交换文件上。这样你就可以很方便地修改超大型的文件了(最大可以到2 GB)。但有一点是需要注意的是,Java是调用操作系统的"文件映射机制"来提升性能的。

  RandomAccessFile类的应用:

RandomAccessFile类的应用RandomAccessFile类的应用代码

  RandomAccessFile 插入写示例:

RandomAccessFile 插入写

  我们可以利用RandomAccessFile来实现文件的多线程的下载,也就是多线程下载一个文件时,将文件分成几块,每块用不同的线程进行下载。下面是一个利用多线程在写文件时的例子,其中预先分配文件所需要的空间,然后在所分配的空间中进行分块,然后写入:

利用RandomAccessFile实现文件多线程的下载RandomAccessFile与多线程

     总结一下上文,上文主要是通过三部分来介绍Java RandomAccessFile用法,首先是RandomAccessFile的基本内容和一些类的使用方法,然后是介绍了内存映射文件的基本内容和它MappedByteBuffer 子类的使用和方法,还有一些其他的基本内容简介,最后是介绍RandomAccessFile类的应用,使用RandomAccessFile来实现文件多线程的下载等等。

赞(2)
踩(1)
分享到:
华为认证网络工程师 HCIE直播课视频教程