偶遇RandomAccessFile

一、前言

  本来在研究NIO,别人举的栗子里面,看到一个RandomAccessFile类,之前没见过,就去看了一下,现将相关内容记录如下

二、正文

  RandomAccessFile直接继承自Object,并且实现DataInput和DataOutput接口,它不属于InputStream和OutputStream类系的,并不是针对流的操作,它能在读取文件的时候前后移动,这个是和其他针对流操作的I/O类的本质区别。

  基本上,RandomAccessFile的工作方式是,把DataInputStream和DataOutputStream粘起来,再加上它自己的一些方法,比如定位用的getFilePointer( ),在文件里移动用的seek( ),以及判断文件大小的length( )。此外,它的构造函数还要一个表示以只读方式("r"),还是以读写方式("rw")打开文件的参数 (和C的fopen( )一模一样),它不支持只写文件。它支持对文件随机访问的读取和写入,即我们可以在指定的位置从文件读取/写入数据。

  平时,我们如果要往一个文件末尾追加一些数据,我们会将文件加载到内存,然后进行操作,但是如果文件本身非常大,比如好几G的量,那么普通的电脑承受不了,我们这时就可以使用RandomAccessFile,它无需将文件内容加载在内存,便可以在文件末尾追加内容。当然,有可能很多人会问,这个RandomAccessFile可以在文件指定位置插入数据吗?答案是:RandomAccessFile只能在指定位置修改数据,并不能插入数据(据我所知貌似没有哪个类支持在某个文件某个位置插入数据吧)。

  RandomAccessFile在读取等长数据的情况下也有优势。

  下面给出RandomAccessFile相关使用实例,先看下要操作的文件内容:

  

  

//实例一,从指定位置读取文件
package com.randomaccessfile.demo;

import java.io.RandomAccessFile;

/**
 *
 * @author cyg
 * @date 2017-6-3 下午02:33:13
 * @description 随机读取文件的内容
 */
public class Demo1 {
    public static void main(String[]args) throws Exception{
        //文件内容:hello world!
        RandomAccessFile raf = new RandomAccessFile("C:\\Users\\jackalc\\Desktop\\demo.txt", "r");
        System.out.println("在未指定位置之前,文件指针:"+raf.getFilePointer());
        raf.seek(6);//指定文件指针位置,从0开始
        System.out.println("在指定位置之后,文件指针:"+raf.getFilePointer());
        int readLength = 0;
        byte [] bytes = new byte[1024];
        while((readLength=raf.read(bytes))>0){
            System.out.println(new String(bytes,0,readLength));
        }
    }
}

//输出
在未指定位置之前,文件指针:0
在指定位置之后,文件指针:6
world!
//实例二,文件末尾追加内容
package com.randomaccessfile.demo;

import java.io.RandomAccessFile;

/**
 *
 * @author cyg
 * @date 2017-6-3 下午02:33:13
 * @description 文件末尾追加内容
 */
public class Demo2 {
    public static void main(String[]args) throws Exception{
        //文件内容:hello world!
        RandomAccessFile raf = new RandomAccessFile("C:\\Users\\jackalc\\Desktop\\demo.txt", "rw");//读写方式打开
        raf.seek(raf.length());//将文件的指针移动到原先内容最后一个字节的后面
        raf.write("最末尾追加的内容".getBytes());
    }
}

  实例二运行后,文件内容变更为:

  

//实例三,在文件指定位置修改文件
package com.randomaccessfile.demo;

import java.io.RandomAccessFile;

/**
 *
 * @author cyg
 * @date 2017-6-3 下午02:33:13
 * @description 在文件指定位置修改文件
 */
public class Demo3 {
    public static void main(String[]args) throws Exception{
        //文件内容:hello world!
        RandomAccessFile raf = new RandomAccessFile("C:\\Users\\jackalc\\Desktop\\demo.txt", "rw");//读写方式打开
        raf.seek(6);//"6"是“w”所在的位置
        raf.write("我现在在指定的位置修改内容,我会覆盖从指定位置开始,和我等长的文件内容!".getBytes());
    }
}

  实例三运行之后,文件内容变更成这样:

  如果想要在文件指定位置插入数据,而不是修改数据,要怎么操作呢?RandomAccessFile并没有提供这个方法,对于这个需求,我们可以将指定位置后面的内容先存储到临时文件里面,然后等内容插入完,我们再将临时文件的内容插入到刚刚插入的内容后面,贴一下别人的代码(原文见“三、连接”处):

//实例四,在文件指定位置插入内容
package com.randomaccessfile.demo;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.RandomAccessFile;

/**
 *
 * @author cyg
 * @date 2017-6-3 下午02:33:13
 * @description 在文件指定位置插入内容
 */
public class Demo4 {
    public static void main(String[] args) {
        //文件内容:hello world!
        String path="C:\\Users\\jackalc\\Desktop\\demo.txt";
        insert(path, 6, "这是我需要插入的内容,不覆盖原先的内容");
    }
    /**
     * 实现向指定位置
     * 插入数据
     * @param fileName 文件名
     * @param points 指针位置
     * @param insertContent 插入内容
     * **/
    public static void insert(String fileName,long points,String insertContent){
        try{
        File tmp=File.createTempFile("tmp", null);
        tmp.deleteOnExit();//在JVM退出时删除  

        RandomAccessFile raf=new RandomAccessFile(fileName, "rw");
        //创建一个临时文件夹来保存插入点后的数据
        FileOutputStream tmpOut=new FileOutputStream(tmp);
        FileInputStream tmpIn=new FileInputStream(tmp);
        raf.seek(points);
        /**将插入点后的内容读入临时文件夹**/  

        byte [] buff=new byte[1024];
        //用于保存临时读取的字节数
        int hasRead=0;
        //循环读取插入点后的内容
        while((hasRead=raf.read(buff))>0){
            // 将读取的数据写入临时文件中
            tmpOut.write(buff, 0, hasRead);
        }  

        //插入需要指定添加的数据
        raf.seek(points);//返回原来的插入处
        //追加需要追加的内容
        raf.write(insertContent.getBytes());
        //最后追加临时文件中的内容
        while((hasRead=tmpIn.read(buff))>0){
            raf.write(buff,0,hasRead);
        }
        }catch(Exception e){
            e.printStackTrace();
        }
    }
}

  实例四运行完之后,文件内容如下:

三、链接

1、http://blog.csdn.net/czplplp_900725/article/details/37809579

2、http://www.cnblogs.com/skywang12345/p/io_26.html

3、http://baike.baidu.com/link?url=XqFXrey5USYJQ9kJVKufnL18QtobxJ6DRvYVfjUhXINC8Afctou3qKiN12ZPFSPUNLzyqMGa1ttl12zR7ZG-DA_hv7m3_MLmnSWNdYT6-re

四、联系本人

  为方便没有博客园账号的读者交流,特意建立一个企鹅群(纯公益,非利益相关),读者如果有对博文不明之处,欢迎加群交流:261746360,小杜比亚-博客园

时间: 2024-10-13 05:04:15

偶遇RandomAccessFile的相关文章

RandomAccessFile拆分合并文件

import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.RandomAccessFile; import java.io.SequenceInputStream; import java.util.Vector; public class RandonFileAccessTest { public static void main(String[]

偶遇linux,搞大了头

偶遇网站打不开,人懵逼了,然后各种查询资料,查到可能跟服务器的问题有关,于是乎连接linux服务器,开始一段苦逼旅程. 其实主要是一些简单的linux命令,对我这个没怎么接触linux的小白来说,何等的虐待.首先,命令行 df -hl 查看硬盘空间详细,查询到可使用内存为16m,已使用100%.所以暂时把网站问题归类为硬盘空间不足引起的.下面是一些相关的linux命令,自己做个笔记,以便以后查看. cl ..    =>    查看硬盘空间文件夹: cl alidata    =>   查看相

[Java开发之路](7)RandomAccessFile类详解

RandomAccessFile适用于大小已知的记录组成的文件,提供的对文件访问,既可以读文件,也可以写文件,并且支持随机访问文件,可以访问文件的任意位置.文件中记录的大小不一定都相同,只要我们知道记录的大小和位置.但是该类仅限于操作文件. RandomAccessFile不属于InputStream和OutputStream继承层次结构中的一部分.除了实现DataInput和DataOutput接口之外(DataInputStream和DataOutputStream也实现了这两个接口),它和

深入理解JAVA I/O系列四:RandomAccessFile

一.简述 这个是JDK上的截图,我们可以看到它的父类是Object,没有继承字节流.字符流家族中任何一个类.并且它实现了DataInput.DataOutput这两个接口,也就意味着这个类既可以读也可以写. 二.存在的意义 1.是JAVA I/O流体系中功能最丰富的文件内容访问类,它提供了众多方法来访问文件内容. 2.由于可以自由访问文件的任意位置,所以如果需要访问文件的部分内容,RandomAccessFile将是更好的选择. 3.可以用来访问保存数据记录的文件,文件的记录的大小不必相同,但是

随机访问流 RandomAccessFile

RandomAccessFile不属于流,是Object的子类 但是它融合了InputStream和OutputStream的功能,支持对文件随机读取和写入 构造方法 public RandomAccessFile(String name,String mode):第一个参数是文件路径,第二个参数是操作文件的模式 模式有4种,但是最常用的"rw",这种方法表示既可以写数据,也可以输出数据 package cn.idcast; import java.io.IOException; im

RandomAccessFile 文件读写中文乱码解决方案!

RandomAccessFile 读写文件时,不管文件中保存的数据编码格式是什么   使用 RandomAccessFile对象方法的 readLine() 都会将编码格式转换成 ISO-8859-1 所以 输出显示是还要在进行一次转码 例子: package fileReadAndWrite; import java.io.FileNotFoundException; import java.io.IOException; import java.io.RandomAccessFile; /*

Java篇:RandomAccessFile

1 package ares.io; 2 3 import java.io.File; 4 import java.io.IOException; 5 import java.io.RandomAccessFile; 6 import java.util.Arrays; 7 8 //Java文件模型操作 9 public class RafSample { 10 11 public static void main(String[] args) throws IOException { 12 /

File操作-RandomAccessFile

一.知识点笔记 1. 文件操作——RandomAccessFile 1. 创建对象 Java提供了一个可以对文件随机访问的操作,访问包括读和写操作.该类名为RandomAccessFile.该类的读写是基于指针的操作. 1.1.2. 只读模式 RandomAccessFile在对文件进行随机访问操作时有两个模式,分别为只读模式(只读取文件数据),和读写模式(对文件数据进行读写). 只读模式: 在创建RandomAccessFile时,其提供的构造方法要求我们传入访问模式: RandomAcces

Java基础知识强化之IO流笔记63:随机访问流RandomAccessFile

1. 随机访问流RandomAccessFile RandomAccessFile类不属于流,是Object类的子类.但它融合了InputStream和OutputStream的功能.支持对随机访问文件的读取和写入. RandomAccessFile的构造方法: 构造方法摘要 RandomAccessFile(File file, String mode)           创建从中读取和向其中写入(可选)的随机访问文件流,该文件由 File 参数指定. RandomAccessFile(St