《文件与I/O流》第5节:RandomAccessFile类

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了《文件与I/O流》第5节:RandomAccessFile类相关的知识,希望对你有一定的参考价值。


RandomAccessFile是Java语言输入输出流体系中功能最丰富的文件内容访问类,它提供了很多方法来访问文件内容,它既可以读取文件内容,也可以向文件输出数据。与普通的输入输出流不同的是:RandomAccessFile支持“随机访问”的方式,所谓“随机访问”就是指程序可以直接跳转到文件的任意位置来读写数据。由于RandomAccessFile可以自由访问文件的任意位置,所以如果只需要读取文件部分内容,而不是把文件从头读到尾,RandomAccessFile将是最好的选择。相应的,如果希望从文件的任意位置开始输出数据,也可以使用RandomAccessFile完成,因为RandomAccessFile允许自由定位指针的位置。RandomAccessFile的方法虽然多,但它有一个最大的局限,就是只能读写文件,不能读写其他类型的数据源。

RandomAccessFile对象也包含了一个指针用以标识当前读写处的位置,当程序新创建一个RandomAccessFile对象时,该对象的文件记录指针位于文件头,当读/写了n个字节后,文件记录指针将会向后移动n个字节。除此之外,RandomAccessFile可以自由移动该指针,既可以向前移动,也可以向后移动。RandomAccessFile用来操作文件指针的方法如表12-11所示。

表12-11 RandomAccessFile操作文件指针的方法

方法

功能

long getFilePointer()

返回文件指针的当前位置

void seek(long pos)

将指针定位到pos位置

RandomAccessFile既可以读文件,也可以写文件,所以它既包含了InputStream三个版本的read()方法,也包含了OutputStream三个版本的write()方法,除此之外,RandomAccessFile还包含了一系列的readXXX()和 writeXXX()方法来完成输入、输出。

RandomAccessFile类有两个构方法,这两个构造方法基本相同,只是指定文件的形式不同而已,一个使用String参数来指定文件名,一个使用File参数来指定文件本身。此外,创建RandomAccessFile对象时还需要指定一个mode参数,该参数指定RandomAccessFile的访问模式,该参数有如下4个值。

  1. "r":以只读方式打开指定文件。如果试图对该RandomAccessFile执行写入数据的方法,都将抛出IOException异常。
  2. "rw":以读、写方式打开指定文件。如果该文件尚不存在,则尝试创建该文件。
  3. "rws":以读、写方式打开指定文件。相对于"rw"模式,还要求对文件的内容或元数据的每个更新都同步写入到底层存储设备。
  4. "rwd":以读、写方式打开指定文件。相对于"rw"模式,还要求对文件内容的每个更新都同步写入到底层存储设备。

需要注意:RandomAccessFile依然不能向文件的指定位置插入内容,如果直接将文件记录指针移动到中间某位置后开始输出,则新输出的内容会覆盖文件中原有的内容。如果需要向指定位置插入内容,程序需要先把插入点后面的内容读入缓冲区,等把需要插入的数据写入文件后,再将缓冲区的内容追加到文件后面。下面的【例12_08】展示了用RandomAccessFile类对象随机访问文件的效果。为了程序能正确运行,读者需要先在D盘根目录下建立一个12_08.txt,并在文件中输入“Hello World!”。

【例12_08 随机访问文件】

Exam12_08.java

import java.io.*;
public class Exam12_08
public static void main(String[] args)
RandomAccessFile ras = null;
try
ras = new RandomAccessFile("D:/12_08.txt","rw");
ras.seek(6);//指针移动到下标为6的位置
System.out.print("指针移动到6的位置开始读数据:");
int r;
while ((r=ras.read())!=-1)
System.out.print((char)r);

System.out.println();//换行
System.out.print("以China覆盖World:");
ras.seek(6);//把指针重新定位值6的位置
ras.write(C);
ras.write(h);
ras.write(i);
ras.write(n);
ras.write(a);
//把指针重新定位到文件开始位置
ras.seek(0);
while ((r=ras.read())!=-1)
System.out.print((char)r);

System.out.println();//换行
ras.seek(6);//再次把指针定位到6的位置
byte[] buff = new byte[1024];
int len = ras.read(buff);//把China读入字节数组
System.out.print("插入great :");
ras.seek(6);//把指针重新定位值6的位置
ras.write(g);
ras.write(r);
ras.write(e);
ras.write(a);
ras.write(t);
ras.write( );
//把刚才存入字节数组的China重新写入文件:
ras.write(buff,0,len);
ras.seek(0);//把指针重新定位到文件开始位置
while ((r=ras.read())!=-1)
System.out.print((char)r);

catch (FileNotFoundException e)
e.printStackTrace();
catch (IOException e)
e.printStackTrace();
finally
if(ras!=null)
try
ras.close();
catch (IOException e)
e.printStackTrace();




【例12_08】首先把指针移动到下标为6的位置开始读取文件内容,之后又把指针再次移动到下标为6的位置写入“China”覆盖了原来的“World”,然后再次把指针移动到下标为6的位置,读取“China!”并保存到一个足够大的buff数组中,然后以“great ”覆盖了原来的“China!”,之后把数组buff数组中的数据加入到文件的末尾,这样就形成了在“Hello”和“China”中间插入“great”的效果。需要注意,如果需要临时保存的数据很多,必须把这些数据存入一个文件中,然后在需要插入的位置重新读出并插入【例12_08】的运行结果如图12-10所示。

第十二章《文件与I/O流》第5节:RandomAccessFile类_Java

图12-10【例12_08】运行结果

运行完程序后,读者可以打开12_08.txt观察文件内容的变化。

除阅读文章外,各位小伙伴还可以点击这里观看我在本站的视频课程学习Java!

 

以上是关于《文件与I/O流》第5节:RandomAccessFile类的主要内容,如果未能解决你的问题,请参考以下文章

《文件与I/O流》第1节:Java的文件管理

《文件与I/O流》第4节:对象序列化

Java高级特性 第4节 输入输出流

python之文件读写

Java I/O系列

文件I/O