2018-04-24

RandomAcessFile类基本使用详解



目录

1、构造函数
2、常用的方法
--2.1、最基本的方法----read()和write()
--2.2、其他的读写方法
3、RandomAcessFile文件复制



java.io.RandomAcessFile可以对文件进行随机的读取和写入。

1、构造函数

//创建从中读取和向其中写入的随机访问文件流,该文件由File参数指定
public RandomAcessFile(File file,String mode);

//创建从中读取和向其中写入的随机访问文件流,该文件具有指定的名称
public RandomAccessFile(String name,String mode);

参数说明:

r:read w:write s:synchronously d:device

mode:

r :以只读方式打开

rw :以读写方式打开(如果使用的是上面的第一个构造函数,如果该文件不存在,则尝试创建该文件)

rws:以读写方式打开,还要求对文件的内容或元数据的每个更新都同步写入到底层存储设备。 rws模式是同步模式,你每写入一个字节的数据,数据就立马写入到设备上面,可以保证由该调用对此文件所做的所有更改均被写入该设备。这对确保在系统崩溃时不会丢失重要信息特别有用。

rwd:以读写方式打开,还要求对文件的内容的每个更新都同步写入到底层存储设备。rwd模式可用于减少执行的 I/O 操作数量。

使用 rwd 仅要求更新要写入存储的文件的内容;使用 rws 要求更新要写入的文件内容及其元数据,这通常要求至少一个以上的低级别 I/O 操作。

2、常用的方法

2.1、最基本的方法----read()和write()

//从此文件中读取一个数据字节(8bit)
public int read();

//向此文件中写入一个数据字节(8bit)
public int write(int b);

我们都知道在Java中int占4个字节(32bit),如果我们要将一个int数据写入到文件中那么每次只能写入1个字节,就意味着我们必须要将int型数据拆分为4次来写入到文件中,同样的,在读取数据的时候也是一样的。

import java.io.File;
import java.io.RandomAccessFile;

/**
 * RandomAccessFile随机访问文件的读取和写入
 * 在这里我们new两个RandomAccessFile的实例出来,一个用来向文件中存入数据,另一个用来读取文件中的数据,假设demo.dat文件已经存在
 * @author Administrator
 *
 */
public class RandomAccessFileDemo01 {
    public static void main(String[] args){
        try {
            //构造方法一,该实例用来向文件中写入数据
            RandomAccessFile raf=new RandomAccessFile("demo.dat", "rw");
            //构造方法二,该实例用来读取文件中的数据
            File file=new File("demo.dat");
            RandomAccessFile raf1=new RandomAccessFile(file, "rw");
            
            /**
             * public void write(int b)throws IOException
             * 每次只写入一个字节,写入整数的"低8位"
             */
            int x=999999999;//二进制表示为:00111011 10011010 11001001 11111111
            raf.write((x>>>24)&0xff);//写入高8位:00111011
            System.out.println(Integer.toBinaryString((x>>>24)&0xff));
            raf.write(x>>>16&0xff);//写入中上8位:10011010
            System.out.println(Integer.toBinaryString((x>>>16)&0xff));
            raf.write(x>>>8&0xff);//写入中下8位:11001001
            System.out.println(Integer.toBinaryString((x>>>8)&0xff));
            raf.write(x);//写入低8位置:11111111
            System.out.println(Integer.toBinaryString((x>>>0)&0xff));
            raf.close();
            
            
            /**
             * 从当前文件中读取一个字节,将该字节存入返回的int中
             * 若返回值为-1,则说明读取到了文件的末尾(EOF:END OF FILE)
             */
            int a=raf1.read();
            int b=raf1.read();
            int c=raf1.read();
            int d=raf1.read();
            //将每次读取出来的数据依次算术移位
            int readX=(a<<24)+(b<<16)+(c<<8)+(d);
            System.out.println("读取出来的数据为:"+readX);
            raf1.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        
    }
}

有人会说这样做好麻烦啊!是的,这样做确实是很麻烦,强大的Java已经给我们封装好了其他的方法了,但是,我们通过查看源码可以知道其他已经封装好的方法都是以上面所述的方法为基础的。

2.2、其他的读写方法:

//将最多 b.length 个数据字节从此文件读入 byte 数组
public int read(byte[] b);
//将 b.length 个字节从指定 byte 数组写入到此文件
public void write(byte[] b);

//最多 len 个数据字节从此文件读入 byte 数组,off是写入数据时字节数组b中的初始偏移量
public int read(byte[] b,int off,int len);
//将 len 个字节从指定 byte 数组写入到此文件,并从偏移量 off 处开始
public void write(byte[] b,int off,int len);

//从此文件读取一个 boolean。此方法从该文件的当前文件指针开始读取单个字节。值 0 表示 false。其他任何值表示 true
public final boolean readBoolean();
//按单字节值将 boolean 写入该文件
public final void writeBoolean(boolean v);

//从此文件读取一个有符号的八位值。此方法从该文件的当前文件指针开始读取一个字节
public final byte readByte();
//按单字节值将 byte 写入该文件
public final void writeByte(int v);
//按字节序列将该字符串写入该文件。该字符串中的每个字符均按顺序写出,并丢弃其高八位
public final void writeBytes(String s);


//从此文件读取一个字符。此方法从该文件的当前文件指针开始读取两个字节
public final char readChar();
//按双字节值将 char 写入该文件,先写高字节
public final void writeChar(int v);
//按字符序列将一个字符串写入该文件。每个字符均写入数据输出流
public final void writeChars(String s);

//从此文件读取一个 double
public final double readDouble();
//使用 Double 类中的 doubleToLongBits 方法将双精度参数转换为一个 long,然后按八字节数量将该 long 值写入该文件,先定高字节
public final void writeDouble(double v);

//从此文件读取一个 float
public final float readFloat();
//使用 Float 类中的 floatToIntBits 方法将浮点参数转换为一个 int,然后按四字节数量将该 int 值写入该文件,先写高字节
public final void writeFloat(float v);

//从此文件读取一个有符号的 32 位整数。此方法从该文件的当前文件指针开始读取 4 个字节
public final int readInt();
//按四个字节将 int 写入该文件,先写高字节
public final void writeInt(int v);

//从此文件读取一个有符号的 64 位整数。此方法从该文件的当前文件指针开始读取八个字节
public final long readLong();
//按八个字节将 long 写入该文件,先写高字节
public final void writeLong(long v);

以上基本上就是RandomAcessFile类所有的读写方法

3、RandomAcessFile文件复制:

import java.io.RandomAccessFile;

public class RandomAccessFileDemo02 {

    public static void main(String[] args) {
        /**
         * 案例:两个文件之间的复制
         * 1.先new一个RandomAcessFile用来读取文件里面的数据
         * 2.继续new一个RandomAcessFile用户写入读取到的数据
         * 3.直到读取数据的返回值为-1时则说明读取完毕
         */
        try {
            //可以使用大概5MB大小的文件来测试
            long begin=System.currentTimeMillis();
            RandomAccessFile  src=new RandomAccessFile("src.txt", "rw");
            RandomAccessFile dest=new RandomAccessFile("dest.txt", "rw");
            
            /**
             * 按一个字节一个字节的读取
             * 按一个字节一个字节的写入
             * 
             */
            int flag=0;
            while((flag=src.read())!=-1){
                dest.write(flag);
            }
            if(flag==-1){
                System.out.println("文件复制成功!");
            }else{
                System.out.println("文件复制失败!");
            }
            src.close();
            dest.close();
            long end=System.currentTimeMillis();
            System.out.println("按字节读写的时间为:"+(end-begin));
            /**
             * 使用字节数组来读取和写入
             */
            
            long begin1=System.currentTimeMillis();
            RandomAccessFile  src1=new RandomAccessFile("src1.txt", "rw");
            RandomAccessFile dest1=new RandomAccessFile("dest1.txt", "rw");
            //建立一个文件缓冲区,每次读取buffer.length大小的数据
            byte[] buffer=new byte[1024*8];
            int flag1=0;
            //每一次循环读写的数据量为1024*8个字节的数组,返回值为实际读到的字节数
            while((flag1=src1.read(buffer))!=-1){
                dest1.write(buffer);
            }
            if(flag1==-1){
                System.out.println("文件复制成功!");
            }else{
                System.out.println("文件复制失败!");
            }
            src1.close();
            dest1.close();
            long end1=System.currentTimeMillis();
            System.out.println("按字节数组读写的时间为:"+(end1-begin1));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}

运行结果:

文件复制成功!

按字节读写的时间为:22148

文件复制成功!

按字节数组读写的时间为:12

以上的数据说明,我们如果要提高文件的读写效率,那么就要减少I/O的次数。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,271评论 5 466
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,725评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,252评论 0 328
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,634评论 1 270
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,549评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 47,985评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,471评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,128评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,257评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,233评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,235评论 1 328
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,940评论 3 316
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,528评论 3 302
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,623评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,858评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,245评论 2 344
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,790评论 2 339

推荐阅读更多精彩内容