[Java开发之路](7)RandomAccessFile类详解

最后更新于:2022-04-01 09:59:39

RandomAccessFile适用于大小已知的记录组成的文件,提供的对文件访问,既可以读文件,也可以写文件,并且支持随机访问文件,可以访问文件的任意位置。文件中记录的大小不一定都相同,只要我们知道记录的大小和位置。但是该类仅限于操作文件。 RandomAccessFile不属于InputStream和OutputStream继承层次结构中的一部分。除了实现DataInput和DataOutput接口之外(DataInputStream和DataOutputStream也实现了这两个接口),它和这两个继承层次结构没有任何关系,它甚至不使用InputStream和OutputStream类中已经存在的任何功能;它是一个完全独立的类,从头开始编写其所有的方法(大多数都是本地的)。这么做是因为RandomAccessFile拥有和别的IO类型本质上不同的行为,因为我们可以在一个文件内向前和向后移动。它是一个直接继承Object的,独立的类。 本质上说,RandomAccessFile的工作方式类似于把DataInputStream和DataOutputStream结合起来,还添加了一些方法,其中方法getFilePointer( )用来查找当前所处的文件位置,seek( )用来在文件内移至新的位置,length( )用来判断文件大小。此外,它的构造方法还需要一个参数来表示打开模式(只读方式 r 读写方式 rw),它不支持只写文件。 只有RandomAccessFile支持搜寻方法(seek()),并且这个方法也只适用于文件。BufferedInputStream却只能允许标注(mark())位置(其值存储在内部某个变量内)和重新设定位置(reset()),但是这些功能有限,不是非常实用。 在JDK 1.4中,RandomAccessFile的绝大多数功能(但不是全部)已经被nio内存映射文件给取代了。 **方法:** | 方法 | 描述 | |-----|-----| | void close() | 关闭此随机访问文件流并释放与该流关联的所有系统资源。 | | FileChannel getChannel () | 返回与此文件关联的唯一 FileChannel 对象。 | | FileDescriptor getFD () | 返回与此流关联的不透明文件描述符对象。 | | long getFilePointer () | 返回此文件中的当前偏移量,用来查找当前所处的位置。 | | long length() | 返回此文件的长度。 | | int read() | 从此文件中读取一个数据字节 | | int read(byte[] b) | 将最多 b.length 个数据字节从此文件读入 byte 数组。 | | int read(byte[] b,int off,int len) | 将最多 len 个数据字节从此文件读入 byte 数组。 | | boolean readBoolean() | 从此文件读取一个 boolean。 | | byte readByte() | 从此文件读取一个有符号的八位值。 | | char readChar() | 从此文件读取一个字符 | | double readDouble() | 从此文件读取一个 double。 | | float readFloat() | 从此文件读取一个 float。 | | void readFully(byte[] b) | 将 b.length 个字节从此文件读入 byte 数组,并从当前文件指针开始。 | | void readFully(byte[] b,int off,int len) | 将正好 len 个字节从此文件读入 byte 数组,并从当前文件指针开始。 | | int readInt() | 从此文件读取一个有符号的 32 位整数。 | | String readLine() | 从此文件读取文本的下一行。 | | long readLong() | 从此文件读取一个有符号的 64 位整数。 | | short readShort() | 从此文件读取一个有符号的 16 位数。 | | int readUnsignedByte() | 从此文件读取一个无符号的八位数 | | int readUnsignedShort() | 从此文件读取一个无符号的 16 位数。 | | String readUTF() | 从此文件读取一个字符串。 | | void seek(long pos) | 设置到此文件开头测量到的文件指针偏移量,在该位置发生下一个读取或写入操作。 | | void setLength(long newLength) | 设置此文件的长度。 | | int skipBytes(int n) | 尝试跳过输入的 n 个字节以丢弃跳过的字节。 | | void write(byte[] b) | 将 b.length 个字节从指定 byte 数组写入到此文件,并从当前文件指针开始。 | | void write(byte[] b, int off, int len) | 将 len 个字节从指定 byte 数组写入到此文件,并从偏移量 off 处开始。 | | void write(int b) | 向此文件写入指定的字节。 | | void writeBoolean(boolean v) | 按单字节值将 boolean 写入该文件。 | | void writeByte(int v) | 按单字节值将 byte 写入该文件 | | void writeBytes(String s) | 按字节序列将该字符串写入该文件。 | | void writeChar(int v) | 按双字节值将 char 写入该文件,先写高字节。 | | void writeChars(String s) | 按字符序列将一个字符串写入该文件。 | | void writeDouble(double v) | 使用 Double 类中的 doubleToLongBits 方法将双精度参数转换为一个 long,然后按八字节数量将该 long 值写入该文件,先定高字节。 | | void writeFloat(float v) | 使用 Float 类中的 floatToIntBits 方法将浮点参数转换为一个 int,然后按四字节数量将该 int 值写入该文件,先写高字节。 | | void writeInt(int v) | 按四个字节将 int 写入该文件,先写高字节。 | | void writeLong(long v) | 按八个字节将 long 写入该文件,先写高字节 | | void writeShort(int v) | 按两个字节将 short 写入该文件,先写高字节。 | | void writeUTF(String str) | 使用 modified UTF-8 编码以与机器无关的方式将一个字符串写入该文件。 | **案例:** ~~~ package com.qunar.bean; import java.io.File; import java.io.RandomAccessFile; import java.util.Arrays; public class FileDemo { public static void main(String[] args) { String pathname = "D:\\Recommended system.txt"; // 创建文件实例 File file = new File(pathname); try { // 判断文件是否存在 if(!file.exists()){ file.createNewFile(); }//if // 读写方式打开文件 RandomAccessFile randomAccessFile = new RandomAccessFile(file, "rw"); System.out.println("当前所处的位置:"+randomAccessFile.getFilePointer()); // write 从当前指针开始写入,写入一个字节 randomAccessFile.write('A'); System.out.println("当前所处的位置:"+randomAccessFile.getFilePointer()); randomAccessFile.write('B'); int num = 0x7fffffff; // 如果用write方法,每次只能写一个字节,需要写4次 randomAccessFile.write(num >>> 24); randomAccessFile.write(num >>> 16); randomAccessFile.write(num >>> 8); randomAccessFile.write(num); System.out.println("当前所处的位置:"+randomAccessFile.getFilePointer()); // 或者是用writeInt方法 一次写入 randomAccessFile.writeInt(num); System.out.println("当前所处的位置:"+randomAccessFile.getFilePointer()); // 文件指针指向文件开头 randomAccessFile.seek(0); // 一次性读取 把文件中内容都读到字节数组中 byte[] buffer = new byte[(int)randomAccessFile.length()]; randomAccessFile.read(buffer); for (byte b : buffer) { // 16进制输出 System.out.print(Integer.toHexString(b)+" "); }//for randomAccessFile.close(); } catch (Exception e) { e.printStackTrace(); } } } ~~~ ~~~ package com.qunar.bean; import java.io.File; import java.io.RandomAccessFile; public class FileDemo { public static void main(String[] args) { String pathname = "D:\\Recommended system.txt"; // 创建文件实例 File file = new File(pathname); try { // 判断文件是否存在 if(!file.exists()){ file.createNewFile(); }//if // 读写方式打开文件 RandomAccessFile randomAccessFile = new RandomAccessFile(file, "rw"); // 写值 for(int i = 0;i < 5;++i){ randomAccessFile.writeInt(i); }//for // 将文件指针移到第二个Int值后 randomAccessFile.seek(2*4); // 覆盖第三个Int值 randomAccessFile.writeInt(6); // 文件指针指向文件开头 randomAccessFile.seek(0); // 输出 for (int i = 0;i < 5;++i) { System.out.print(randomAccessFile.readInt()+" "); }//for randomAccessFile.close(); } catch (Exception e) { e.printStackTrace(); } } } ~~~ ~~~ package com.qunar.bean; import java.io.File; import java.io.RandomAccessFile; public class FileDemo { public static void main(String[] args) { String pathname = "D:\\Recommended system.txt"; // 创建文件实例 File file = new File(pathname); try { RandomAccessFile randomAccessFile = new RandomAccessFile(file, "rw"); // 以下向file文件中写数据 // 占4个字节 randomAccessFile.writeInt(2015); // 占8个字节 randomAccessFile.writeDouble(12.23); // 占2个字节 randomAccessFile.writeShort(19); System.out.println("当前位置:"+randomAccessFile.getFilePointer()); randomAccessFile.writeUTF("欢迎来到小斯的博客"); System.out.println("当前位置:"+randomAccessFile.getFilePointer()); // 占2个字节 randomAccessFile.writeChar('Y'); System.out.println("当前位置:"+randomAccessFile.getFilePointer()); randomAccessFile.writeUTF("小斯的博客欢迎你"); // 把文件指针位置设置到文件起始处 randomAccessFile.seek(0); System.out.println("读取一个Int值:"+randomAccessFile.readInt()); System.out.println("读取一个Double值:"+randomAccessFile.readDouble()); System.out.println("读取一个Short值:"+randomAccessFile.readShort()); System.out.println("读取一个字符串:"+randomAccessFile.readUTF()); // 将文件指针跳过2个字节 randomAccessFile.skipBytes(2); System.out.println("读取一个字符串:"+randomAccessFile.readUTF()); randomAccessFile.close(); } catch (Exception e) { e.printStackTrace(); } } } ~~~
';