通过前面的学习我们知道,如果准备读文件,需要建立指向该文件的输入流;如果准备写文件,需要建立指向该文件的输出流。那么,能否建立一个流,通过该流既能读文件也能写文件呢?这正是本节要介绍的随机流。
RandomAccessFile类
创建的流称做
随机流
,与前面的输入、输出流不同的是,RandomAccessFile类既不是InputStream类的子类,也不是OutputStream类的子类。但是RandomAccessFile类创建的流的指向既可以作为流的源,也可以作为流的目的地,换句话说,当准备对一个文件进行读写操作时,创建一个指向该文件的随机流即可,这样既可以从这个流中读取文件中的数据,也可以通过这个流写入数据到文件。
以下是RandomAccessFile类的两个构造方法:
1)RandomAccessFile(String name,String mode)
参数name用来确定一个文件名,给出创建的流的源,也是流目的地。参数mode取r(只读)或rw(可读写),决定创建的流对文件的访问权利。
2)RandomAccessFile(File file,String mode)
参数file是一个File对象,给出创建的流的源,也是流目的地。参数mode取r(只读)或rw(可读写),决定创建的流对文件的访问权利。
注意
:RandomAccessFile流指向文件时,不刷新文件。
RandomAccessFile类中有一个方法seek(long a)用来定位RandomAccessFile流的读写位置,其中参数a确定读写位置距离文件开头的字节个数。另外流还可以调用getFilePointer()方法获取流的当前读写位置。RandomAccessFile流对文件的读写比顺序读写更为灵活。
例如,把几个int型整数写入到一个名字为tom.dat文件中,然后按相反顺序读出这些数据:
import java.io.*;
public class Main {
public static void main(String args[]) {
RandomAccessFile inAndOut = null;
int data[] = {1,2,3,4,5,6,7,8,9,10};
try {
inAndOut = new RandomAccessFile("tom.dat","rw");
for(int i=0;i<data.length;i++) {
inAndOut.writeInt(data[i]);
for(long i = data.length-1;i>=0;i--) {
inAndOut.seek(i*4);
System.out.printf("\t%d",inAndOut.readInt());
一个int型数据占4个字节,inAndOut从文件的第36个字节读取最后面的一个整数,每隔4个字节往前读取一个整数
inAndOut.close();
catch(IOException e) {}
}
RandomAccessFile流的常用方法如下:
方法
|
说明
|
close()
|
关闭文件
|
getFilePointer()
|
获取当前读写的位置
|
length()
|
获取文件的长度
|
read()
|
从文件中读取一个字节的数据
|
readBoolean()
|
从文件中读取一个布尔值,0代表false;其他值代表true
|
readByte()
|
从文件中读取一个字节
|
readChar()
|
从文件中读取一个字符(2个字节)
|
readDouble()
|
从文件中读取一个双精度浮点值(8 个字节)
|
readFloat()
|
从文件中读取一个单精度浮点值(4个字节)
|
readFully(byte b[])
|
读b.length字节放入数组b,完全填满该数组
|
readInt()
|
从文件中读取一个int值(4个字节)
|
readLine()
|
从文件中读取一个文本行
|
readLong()
|
从文件中读取一个长型值(8个字节)
|
readShort()
|
从文件中读取一个短型值(2个字节)
|
readUnsignedByte()
|
从文件中读取一个无符号字节(1个字节)
|
readUnsignedShort()
|
从文件中读取一个无符号短型值(2个字节)
|
readUTF()
|
从文件中读取一个UTF字符串
|
seek(long position)
|
定位读写位置
|
setLength(long newlength)
|
设置文件的长度
|
skipBytes(int n)
|
在文件中跳过给定数量的字节
|
write(byte b[])
|
写b.length个字节到文件
|
writeBoolean(boolean v)
|
把一个布尔值作为单字节值写入文件
|
writeByte(int v)
|
向文件写入一个字节
|
writeBytes(String s)
|
向文件写入一个字符串
|
writeChar(char c)
|
向文件写入一个字符
|
writeChars(String s)
|
向文件写入一个作为字符数据的字符串
|
writeDouble(double v)
|
向文件写入一个双精度浮点值
|
writeFloat(float v)
|
向文件写入一个单精度浮点值
|
writeInt(int v)
|
向文件写入一个int值
|
writeLong(long v)
|
向文件写入一个长型int值
|
writeShort(int v)
|
向文件写入一个短型int值
|
writeUTF(String s)
|
写入一个UTF字符串
|
注意
:RandomAccessFile流的readLine()方法在读取含有非ASCⅡ字符的文件时,比如含有汉字的文件,会出现“乱码”现象。因此,需要把readLine()读取的字符串用“iso-8859-1”编码重新编码存放到byte数组中,然后再用当前机器的默认编码将该数组转化为字符串,操作如下:
1.读取
String str = in.readLine();
2.用“iso-8859-1”重新编码
byte b[] = str.getBytes("iso-8859-1");
3.使用当前机器的默认编码将字节数组转化为字符串
String content = new String(b);
如果机器的默认编码是“GB2312”,那么
String content = new String(b);
等同于
String content = new String(b,"GB2312");
例如:
import java.io.*;
public class Main {
public static void main(String args[]) {
RandomAccessFile in = null;
try {
in = new RandomAccessFile("Main.java","rw");
long length = in.length(); //获取文件的长度
long position = 0;
in.seek(position); //将读取位置定位到文件的起始
while(position<length) {
String str = in.readLine();
byte b[] = str.getBytes("iso-8859-1");
str = new String(b);
position = in.getFilePointer();
System.out.println(str);
catch(IOException e) {}
C语言网推出会员服务,提供C/C++/算法/Python等多套视频学练课程+源码资源社群答疑+私活推荐等资源,享受丰富的技术学习到变现的乐趣,以含金量和学习效果勇敢挑战同类辅导! 点击了解开通