RandomAccessFile

本文深入探讨了Java中RandomAccessFile类的使用方法,包括创建对象、读写操作、文件指针控制等核心功能,以及如何高效进行块读写,适用于文件的随机访问需求。

1.创建对象

1)简介

Java提供了一个可以对文件随机访问的操作,访问包括读和写的操作。类名为:RandomAccessFile。该类的读写是基于指针的操作。

RandomAccessFile在对文件进行随机访问操作时有两个模式,分别为只读模式(只读取文件数据) , 和读写模式(对文件数据进行读写)。

 

(1)只读模式

在创建RandomAccessFile时, 其提供的构造方法要求我们传入访问模式:

---------RandomAccessFile(File file,String mode)

---------RandomAccessFile(String filename,String mode)

其中构造方法的第一个参数是需要访问的文件,而第二个参数则是访问模式:"r" :字符串" r”表示对该文件的访问是只读的。

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;

/**
 * 从文件中读取字节
 */
public class RAFDemo2 {
    public static void main(String[] args) throws IOException {

  RandomAccessFile raf = new RandomAccessFile("./raf.dat","r");
        /*
        int read()
        读取一个字节(8位2进制)并以int形式返回,如果返回值为-1
        则表示读取到了文件末尾
         */
        int d = raf.read();
        System.out.println(d);
        d = raf.read();
        System.out.println(d);
        d = raf.read();
        System.out.println(d);
        d = raf.read();
        System.out.println(d);
        d = raf.read();
        System.out.println(d);
    }
}

(2)读写模式

创建一个基于文件访问的读写模式的RandomAccessFile我们只需要在第二个参数中传入”rw" 即可

---RandomAccessFile raf = new RandomAccessFile(file," rw" );

那么这时在使用RandomAccessFile对该文件的访问就是又可读又可写的。

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.Random;

/**
 *          随机  访问  文件
 * java.io.RandomAccessFile
 * RAF是专门用来读写文件数据的API,其基于指针对文件任意位置进行读写
 */
public class RAFDemo1 {
    public static void main(String[] args) throws IOException {

  /*
        RAF常用构造器
        RandomAccessFile(String path, String mode)
        RandomAcceccFile(File file , String mode)
        第一个参数是操作的文件,可以直接给路径也可以给File对象
        第二个参数为操作模式:
        r:只读模式,仅对文件进行读取操作
        rw:对文档既可读又可写
         */
        RandomAccessFile raf =new RandomAccessFile("./raf.dat","rw");
        /*
        void Write(int a)
        向文件写入1个字节,写入的是给定的int值所对应的2进制的“低八位
         */
        raf.write(17);
        raf.write(25);


        System.out.println("写出完毕!");
        raf.close();
    }
}

2.字节数据读写操作

1)write(int b)方法

RandomAccessFile提供了一个可以向文件中写出字节的方法:

--------- void write(int d)

该方法会根据当前指针所在位置处写入一个字节, 是将参数int的”低8位"写出。

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.io.UnsupportedEncodingException;

/**
 * 读写字符串操作
 */
public class WriteStringDemo {
    public static void main(String[] args) throws IOException {

     RandomAccessFile raf = new RandomAccessFile("demo.txt","rw");
        String line = "水电费哈利啊剧倪芳 次AV,发酵后我挨罚hi啊哈";
        /*
        String 提供了将字符串转换为字节的对应方法:
        byte[] getByte(String charsetName)
        参数为指定的字符集,如果该字符集拼写错误则会抛出异常
        UnsupportedEncodingException
         */
        /*
        将字符串咦UTF-8编码转换为一组字节
        UTF-8中编码字节量:
        英文占用1字节,中文占用3字节
         */
        byte[] data = line.getBytes("UTF-8");
        raf.write(data);
        System.out.println("写出完毕!");
        raf.close();
    }
}

2)read()方法

RandomAccessFile提供了一个可以从文件中读取字节的方法:

int read();

该方法会从文件中读取一-个byte(8位)填充到int的低八位,高24位为0,返回值范围正数: 0~ 255,如果返回-1表示读取到了文件末尾!每次读取后自动移动文件指针,准备下次读取。

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;

/**
 * 读取文本数据
 */
public class ReadStringDemo {
    public static void main(String[] args) throws IOException {
        //从raf.dat中将文本信息读取出来
        RandomAccessFile raf = new RandomAccessFile("raf.dat","r");
        //1.从文件中将字节读取出来
        byte[] data = new byte[(int)raf.length()];
        raf.read(data);
        //2将字节还原为字符串
        String str = new String(data,"UTF-8");
        System.out.println(str);
        raf.close();
    }
}

3)read(byte[] b)方法

import java.io.IOException;
import java.io.RandomAccessFile;
/**
 * 提高每次读写的数据量减少实际读写的次数可以提高读写的效率
 * 一次一组字节的读写称为块读写
 * RandomAccessFile提供了一次读写一组数据的相应方法
 */
public class CopyDemo2 {
    public static void main(String[] args) throws IOException {

  RandomAccessFile src = new RandomAccessFile("./Birthday.zip","r");
        RandomAccessFile sec = new RandomAccessFile("./生日.zip","rw");
        /*
        int read(byte[] data)
        该方法读取给定的字节数组总长度的字节量,并装入到该数组中返回值为实际读取到的字节量。
        如果返回值为-1则表示本次读取是在文件末尾
        与int read()方法的区别:
        1:一次读取一组字节
        2:返回值意义不同,read()方法返回的int值就是实际读取的数据(只不过只有低八位二进制有效},
        而read(byte[] data)则是江都区的数据存入给定的数组,返回值仅表示读取到了多少个字节
        戴氏相同点是如果返回值我-1都是表示文件末尾

        void write(byte[] data)
        一次性将给定字节数组中的所有字节写入文件

        void write(byte[] data,int offest , int len)
        一次性将给定字节数组从下标offest处开始的连续len个字节写出
         */
        int len = 0;//用于记录每次实际读取到的字节数
        //1GB = 1024MB;1MB = 1024KB;1KB=1024byte
        byte[] data  = new byte[1024*10];//10kb
        long start = System.currentTimeMillis();
        while((len = src.read(data))!=-1){
            sec.write(data,0,len);
        }
        long end = System.currentTimeMillis();
        System.out.println("复制完毕!耗时为:"+(end-start)+"ms");
        src.close();
        sec.close();
    }
}

4)close()方法

RandomAccessFile在对文件访问的操作全部结束后,要调用close(方法来释放与其关联的所有系统资源。

---------- void close()

RandomAccessFile raf = new RandomAccessFile(file," rw" );..//读写操作



raf.close();//访问完毕后要关闭以释放系统资源。

3.文件指针操作

1)getFilePoint()方法

2)seek()方法

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;

/**
 * 读写基本类型数据以及RAF基于指针的读写操作
 */
public class RAFdemo3 {
    public static void main(String[] args) throws IOException {
        /*
        注:
        data 数据的意思
        文件的后缀名实际上是window操作系统的习惯,用以让windows双击某个文件是使用对应的程序打开,
        一次我们一般用后缀判别文件的类型,比如常见的有:exe,txt,jpg等等;
        但是后缀可以自创,自己清楚该文件数据是什么即可。
         */
        RandomAccessFile raf = new RandomAccessFile("data.txt","rw");
        long pos = raf.getFilePointer();
        //写入一个int最大值
        int imax = Integer.MAX_VALUE;
        System.out.println("pos:"+raf.getFilePointer());

        raf.write(imax>>>24);
        System.out.println("pos:"+raf.getFilePointer());
        raf.write(imax>>>16);
        System.out.println("pos:"+raf.getFilePointer());
        raf.write(imax>>>8);
        System.out.println("pos:"+raf.getFilePointer());
        raf.write(imax);
        System.out.println("pos:"+raf.getFilePointer());
       /*
       RAF提供了方便写出基本类型数据的方法
        */
        //连续写出4个字节,将int值写出,等同于上面的操作
        raf.writeInt(imax);
        System.out.println("pos:"+raf.getFilePointer());
        //连续写出8个字节,将long对应的二进制写出
        raf.writeLong(123L);
        System.out.println("pos:"+raf.getFilePointer());
        raf.writeDouble(123.123);
        System.out.println("pos:"+raf.getFilePointer());
        System.out.println("写出完毕!");
        /*
        void seek(long pos)
        将指针移动到指定位置
         */
        /*
        RAF提供的读取基本啥类型的相关方法如:readInt,ReadLong等
        这些方法内部会连续有读取若干字节来还原对应的基本类型,如果
        在连续读取字节的过程中读到了文件末尾(但是应当读取字节数还
        没有到达,比如int应当连续读取4个字符,但是在这这个过程中就
        读取到了文件末尾)此时会抛出EOFExceptiuon
        EOF:end of file 文件末尾异常
         */
        raf.seek(0);//将指针移动到文件最开始
        //连续读取4个字节并还原为对应的int值
        int d = raf.readInt();
        System.out.println(d);
        System.out.println("pos:"+raf.getFilePointer());

        //读取long
        //1先将指针移动到long的开始位置
       raf.seek(8);

        long l = raf.readLong();
        System.out.println(l);
        System.out.println("pos:"+raf.getFilePointer());
        //读取double
        raf.seek(16);
        double a = raf.readDouble();
        System.out.println(a);
        //将long值改为5566
        //1将指针移动到long的第一个字节位置
        raf.seek(8);
        //2重新写入long值(8字节)覆盖原内容
        raf.writeLong(5566);

        raf.seek(8);
        l = raf.readLong();
        System.out.println(l);


        raf.close();
  }
} 

3)skipBytes()方法

RandomAccessFile 类支持对随机访问文件的读写操作,能够在文件的任意位置进行读写。 #### 构造方法 RandomAccessFile 主要有两个构造方法: - `RandomAccessFile(File file, String mode)`:使用给定的文件对象和访问模式创建一个新的 RandomAccessFile 实例。 - `RandomAccessFile(String name, String mode)`:使用给定的文件名和访问模式创建一个新的 RandomAccessFile 实例[^1]。 #### 功能介绍 RandomAccessFile 的实例可以对文件中随机位置进行读写,展示了其随机访问能力,即可以在文件的任意位置进行读写操作。这一特性使其在断点续传、多线程下载等场景中发挥重要作用。例如在多线程下载中,可将文件分成多个部分,每个线程负责下载并写入自己负责的部分,第一个线程从文件起始位置开始写,第二个线程从 20% 位置开始写,以此类推,最终完成整个文件的下载[^2][^3][^4]。 #### 使用示例 以下是一个使用 RandomAccessFile 将一个整数和一个字符串写入文件,然后将文件指针移回到文件的开头,并从文件中读取并打印这些数据的示例代码: ```java import java.io.File; import java.io.IOException; import java.io.RandomAccessFile; public class RandomAccessFileExample { public static void main(String[] args) { try { // 创建一个新的 RandomAccessFile 实例 RandomAccessFile raf = new RandomAccessFile(new File("test.txt"), "rw"); // 写入一个整数 raf.writeInt(123); // 写入一个字符串 raf.writeUTF("Hello, World!"); // 将文件指针移回到文件的开头 raf.seek(0); // 读取整数 int num = raf.readInt(); // 读取字符串 String str = raf.readUTF(); // 打印读取的数据 System.out.println("Read integer: " + num); System.out.println("Read string: " + str); // 关闭文件 raf.close(); } catch (IOException e) { e.printStackTrace(); } } } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Healer_小振

感谢大佬的支持和鼓励!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值