一、简述
这个是JDK上的截图,我们可以看到它的父类是Object,没有继承字节流、字符流家族中任何一个类。并且它实现了DataInput、DataOutput这两个接口,也就意味着这个类既可以读也可以写。
RandomAccessFile是Java输入/输出流体系中功能最丰富的文件内容访问类,既可以读取文件内容,也可以向文件输出数据。与普通的输入/输出流不同的是,RandomAccessFile支持跳到文件任意位置读写数据,RandomAccessFile对象包含一个记录指针,用以标识当前读写处的位置,当程序创建一个新的RandomAccessFile对象时,该对象的文件记录指针对于文件头(也就是0处),当读写n个字节后,文件记录指针将会向后移动n个字节。除此之外,RandomAccessFile可以自由移动该记录指针
RandomAccessFile包含两个方法来操作文件记录指针
- long getFilePointer():返回文件记录指针的当前位置
- void seek(long pos):将文件记录指针定位到pos位置
RandomAccessFile类在创建对象时,除了指定文件本身,还需要指定一个mode参数
该参数指定RandomAccessFile的访问模式,该参数有如下四个值:
- r:以只读方式打开指定文件。如果试图对该RandomAccessFile指定的文件执行写入方法则会抛出IOException
- rw:以读取、写入方式打开指定文件。如果该文件不存在,则尝试创建文件
- rws:以读取、写入方式打开指定文件。相对于rw模式,还要求对文件的内容或元数据的每个更新都同步写入到底层存储设备,默认情形下(rw模式下),是使用buffer的,只有cache满的或者使用RandomAccessFile.close()关闭流的时候儿才真正的写到文件
- rwd:与rws类似,只是仅对文件的内容同步更新到磁盘,而不修改文件的元数据
二、代码示例
public static void main(String[] args){ RandomAccessFile randomAccessFile = null; try { // 可读写 randomAccessFile = new RandomAccessFile(new File("d:\new.txt"), "rw"); // 写 for (int i = 1; i <= 10; i++) { randomAccessFile.write((i+" 设备名/devicename,设备数量/devicenum ").getBytes());
System.out.println("当前指针位置:"+randomAccessFile.getFilePointer()); }
// randomAccessFile.writeBoolean(true); // randomAccessFile.writeByte(11); // randomAccessFile.writeDouble(12); // randomAccessFile.writeUTF("操作"); // 读 randomAccessFile.seek(0);// 读时指针重新置为开始位置,事实上可以从文件内容的任何位置开始 byte[] bs = new byte[1024]; int len=0; while ((len=randomAccessFile.read(bs))!=-1) { System.out.println(new String(bs, 0, len)); } // System.out.println("readLine:"+ randomAccessFile.readLine()); // System.out.println("readDouble:"+randomAccessFile.readDouble()); // System.out.println("readByte:"+randomAccessFile.readByte()); // System.out.println("readUTF:"+randomAccessFile.readUTF()); // 追加写 randomAccessFile.seek(randomAccessFile.length());// 指针移到文件末尾 randomAccessFile.write((21+" 设备名/devicename,设备数量/devicenum ").getBytes()); // 任意位置插入写 int position = 102; String insetstr = "----------------------"; randomAccessFile.seek(position);// 指定插入的位置 // 先把该位置后的所有内容先缓存起来,防止被覆盖 List<byte[]> blists = new ArrayList<>(); byte[] bs1 = new byte[1024]; while (randomAccessFile.read(bs1)!=-1) { blists.add(bs1); } randomAccessFile.seek(position);// 再次返回指定位置 // 插入要插入的内容 randomAccessFile.write(insetstr.getBytes()); // 再把缓存的内容写入 for (int i = 0; i < blists.size(); i++) { byte[] cachestr = blists.get(i); randomAccessFile.write(cachestr); } } catch (Exception ex) { ex.printStackTrace(); } finally{ if (randomAccessFile!=null) { try { randomAccessFile.close(); } catch (IOException ex) { ex.printStackTrace(); } } } }
文件内容
1 设备名/devicename,设备数量/devicenum 2 设备名/devicename,设备数量/devicenum 3 设备----------------------名/devicename,设备数量/devicenum 4 设备名/devicename,设备数量/devicenum 5 设备名/devicename,设备数量/devicenum 6 设备名/devicename,设备数量/devicenum 7 设备名/devicename,设备数量/devicenum 8 设备名/devicename,设备数量/devicenum 9 设备名/devicename,设备数量/devicenum 10 设备名/devicename,设备数量/devicenum 11 设备名/devicename,设备数量/devicenum 12 设备名/devicename,设备数量/devicenum 13 设备名/devicename,设备数量/devicenum 14 设备名/devicename,设备数量/devicenum 15 设备名/devicename,设备数量/devicenum 16 设备名/devicename,设备数量/devicenum 17 设备名/devicename,设备数量/devicenum 18 设备名/devicename,设备数量/devicenum 19 设备名/devicename,设备数量/devicenum 20 设备名/devicename,设备数量/devicenum 21 设备名/devicename,设备数量/devicenum