RandomAccessFile 随机存取文件流

RandomAccessFile 随机存取文件流

专门用来读写文件数据的类,其基本指针对文件进行随机访问

  • RandomAccessFile 声明在java.io包下,但直接继承于java.lang.Object类。并且它实现了DataInput、DataOutput这两个接口,意味着这个类既可以读也可以写。

  • RandomAccessFile 类支持 “随机访问” 的方式,程序可以直接跳到文件的任意地方来读、写文件
    支持只访问文件的部分内容
    可以向已存在的文件后追加内容 (指定指针位置 ,可以向文件写入内容)

RandomAccessFile 对象包含一个记录指针,用以标示当前读写处的位置。RandomAccessFile 类对象可以自由移动记录指针:

  • long getFilePointer():获取文件记录指针的当前位置

  • void seek(long pos):将文件记录指针定位到 pos 位置,当什么都不写时,第一次操作文件默认从0开始读写文件数据。指针会随着操作而改变位置

指针操作的单位是字节。

RandomAccessFile常用构造器

  • public RandomAccessFile (File file, String mode)
    用指定的文件名来创建一个随机存取文件对象,指定访问模式:

  • public RandomAccessFile (String filepathname, String mode);
    用指定的文件路径来创建一个随机存取文件对象,指定访问模式。

访问模式有以下
“ r ”: 可读,当指定文件不存在时不会创建新文件,编译不会报错,运行时会报文件找不到异常(FileNotFoundException)
" rw ": 可读可写,当指定文件不存在时,会创建新文件
“rwd”: 打开以便读取和写入;同步文件内容的更新
“rws”: 打开以便读取和写入;同步文件内容和元数据的更新

创建RandomAccessFile对象

想要实现对文件随机读写操作,必须声明一个随机访问文件的对象,并为其指定访问模式。通过对象可以调用RandomAccessFile类 的一些常用方法实现对文件更好的读写

RandomAccessFile raf = new RandomAccessFile(File file , String mode);
RandomAccessFile raf = new RandomAccessFile(String filepathname , String mode);

常用方法

需要注意:每次访问完对象文件时,指针都会发生相应的改变,若想读之前的内容,必须重新给指针赋值。

void close() ; 关闭此随机访问文件流并释放与该流关联的所有系统资源。
当流关闭之后不能再继续写出 ,
否则会抛出IO异常: java.io.IOException:Stream Closed 

注意 ** : 程序中打开的文件 IO 资源不属于内存里的资源,垃圾回收机制无法回收该资源,所以应该显式关闭文件 IO 资源。

long getFilePointer() ;返回此文件中的当前偏移量(当前指针位置(指向第几个字节)) 
void seek(long pos) 
设置到此文件开头测量到的文件指针偏移量,在该位置发生下一个读取或写入操作。 
long length() ;返回此文件的长度(字节数)
 int read() ; 从此文件中读取一个数据字节。 
读取一个字节并以int形式返回(读取的数据再int值对应的二进制的低八位上)
如果返回的int值为-1则表示读到了文件末尾
 int read(byte[] b) ; 
 将最多 b.length 个数据字节从此文件读入 byte 数组。
 一次性从文件中读取给定的字节数组总长度的字节量,并存入到该数组中,
 返回值为实际读取到的字节量,如果返回值-1则表示文件末尾 
 int read(byte[] b, int off, int len); 
  从该文件指定起始位置off将最多 len 个数据字节从此文件读入 byte 数组。 
 String readLine() ; 从此文件读取文本的下一行。 
 void setLength(long newLength) ; 设置此文件的长度。 

一次性写多个字节

 void write(byte[] b) 
将 b.length 个字节从指定 byte 数组写入到此文件,并从当前文件指针开始。 
一次性将给定的字节数组中的所有字节写入文件。
 void write(byte[] b, int off, int len) 
将 len 个字节从指定 byte 数组写入到此文件,并从偏移量 off 处开始。 
将给定的字节数组从下标offset处连续len个字节一次性写出到目标文件
void write(byte[] data ,int offset,int raf.read(data))
从指定位置写入实际的字节数。
void write(int b) ;向此文件写入指定的字节。 
虽然参数是int型,但是写入时并不能完整的将int型数据写入文件,
只能从文件中写入1个字节,写入到是给定的int值参数对应的二进制的“低八位”

写入int型参数可以用WriteInt()

void writeInt(int v) 
按四个字节将 int 写入该文件,先写高字节。 
void writeLong(long v) ;按八个字节将 long 写入该文件,先写高字节。 
writeDouble(double v) 
使用 Double 类中的 doubleToLongBits 方法将双精度参数转换为一个 long,
然后按八字节数量将该 long 值写入该文件,先定高字节。

因为 write() 都只能操作字节,所以当需要写入(从程序写入文件)字符串时需要将字符串转换为byte[] 数组。用到如下方法。

byte[] getBytes(),将字符串按照系统默认的编码集转换为byte[]数组.(编码集和字符集一个意思)
byte[] getBytes(String charsetName),将字符串按照指定的字符集转化为byte[]数组
 //写入用户名:
 byte[] data = username.getBytes("UTF-8");//getBytes()使用默认的编码,
 想要指定编码格式,使用重载方法getBytes(String charsetName)
//System.out.println(Arrays.toString(data));//byte[] data = username.getBytes(),[115, 97, 116, 106]
//将数组扩容至32字节,浅层复制,更换引用的指向
 data = Arrays.copyOf(data,32);
 raf.write(data);//写入32字节
 //写入密码,先将密码转成byte数组,
 data = password.getBytes("UTF-8");
 data = Arrays.copyOf(data,32);
 raf.write(data);

因为 read() 都只能操作字节,所以当需要读出(从文件读出到程序中)文件数据时需要将byte[] 数组,转换为字符串形式(String)并且可以指定编码集。用到以下方法。
String类提供了一个构造方法:

  • String(byte bytes[], String charsetName)
    将指定的byte数组中的数据按照指定的字符集转换为字符串
    注意:将byte数组转换为String,指定编码集,byte的默认值空格转换为String 会转成空白,可以直接调用trim()去掉两边的空白

想要将文件中的数据以字符串的形式输出需要创建字符串对象,指定字符集。

//将byte数组转换为String,指定编码集,byte的默认值空格转换为String 会转成空白,可以直接调用trim()去掉两边的空白
String username = new String(data,"UTF-8").trim();

 //读取密码
 data = new byte[32];
 raf.read(data);
 String password = new String(data,"UTF-8").trim();

 //读取昵称
 data = new byte[32];
 raf.read(data);
 String nickname = new String(data,"UTF-8").trim();

 //读取年龄
 int age = raf.readInt();
 System.out.println("username :" + username + " ,password : " + password +" ,nickname :" + nickname +" ,age :"+ age);
 //System.out.println(Arrays.toString(data));
 System.out.println(raf.getFilePointer());

补充:编码集

UTF-8 :万国码。一个字节,中文占三个字节
GBK : 国标编码(中国家标准),英文占1字节,中文占 2字节。
ISO8859-1 :欧洲字符集,网络传输用的是ISO8859-1,不支持中文

编码:字符串->字节数组
解码:字节数组->字符串
当我们将字符串按照指定字符集转换为字节时,如果字符集名字拼写有误,则会抛出异常: java.io.UnsupportedEncodingException

  RandomAccessFile raf = new RandomAccessFile("raf.txt","r");
 //创建一个与文件等长的字符数组,raf.length()返回值是一个long型。
  byte[] data = new byte[(int)raf.length()];
  //一次性将文件中的所有字节读入字节数组
  raf.read(data);
  //想要将文件中的数据以字符串的形式输出需要创建字符串对象,指定字符集。
  String str = new String(data,"UTF-8");
  System.out.println(str);
  //关流,为避免内存浪费。
  raf.close();

RandomAccessFile 如何基于指针读写文件?

① 声明随机读写文件对象,两种方式(两种构造方法),指定文件访问模式
例:
方式一:使用指定路径
RandomAccessFile raf = new RandomAccessFile(String filepathname , String mode)
方式二:使用文件
RandomAccessFile raf = new RandomAccessFile(File file , String mode);

② 使用read() 及重载方法 read(byte[] b), read(byte[] b,int off , int len);将文件中的内容按照指定长度读出存储到 byte[] 数组中
③ 使用write(byte []) 及重载方法write(byte[] b,int off, int len);将byte[] 数组中的数据写入当前指定的文件。
④ 使用seek(long pos) 指定指针位置实现访问文件任意位置数据。如果访问的位置不在文件有效字节范围内会抛异常。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值