RandomAccessFile
是Java输入/输出流体系中功能最丰富的文件内容访问类,它提供了众多的方法来访问文件内容,它既可以读取文件内容,也可以向文件输出数据。并且它支持“任意访问”的方式,程序可以直接跳转到文件的任意位置来读写数据。
如何我们希望值访问文件部分内容,而不是把文件从头读到尾,使用RandomAccessFile将是更好的选择。
如果程序需要向已存在的文件后追加内容,则应该使用RandomAcessFile.
RandomAccessFile对象包含一个记录指针,用来表示当前读写处的位置。
RandomAccessFile包含两个方法来操作文件记录指针:
long getFilePointer() :返回文件记录指针的当前位置
void seek(long pos):将文件记录指针定位到pos位置。
Random访问模式:
"r" : 以只读方式打开指定文件
"rw" : 以读写方式打开指定文件。如果该文件不存在,则尝试创建该文件
"rws" : 同上,但相于"rw"模式,还要求对文件的内容或元数据的每个更新都同步写入到底层存储设备。
"rwd" : 同上,但相于"rw"模式,还要求对文件内容的每个更新都同步写入到底层存储设备。
范例:RandomAccessFile访问指定的中间部分数据
package com.chengxuyuanzhiliu; import java.io.FileNotFoundException; import java.io.IOException; import java.io.RandomAccessFile; public class RandomAccessFileTest { public static void main(String[] args) throws FileNotFoundException, IOException { try(RandomAccessFile raf = new RandomAccessFile("D:/Workspaces/Java/Eclipse/JavaIO/src/com/chengxuyuanzhiliu/RandomAccessFileTest.java", "r")){ //获取RandomAccessFile对象文件指针位置,初始位置0 System.out.println("RandomAccessFile对象文件指针初始位置:"+raf.getFilePointer()); //移动raf的文件记录指针的字节数 raf.seek(300); byte[] bbuf = new byte[1024]; //用来保存实际读取的字节数 int hasRead = 0; //使用循环来重复"取水"过程 while((hasRead = raf.read(bbuf)) > 0){ //取出"竹筒"中的水滴,将字节数组转换成字符串输入 System.out.println(new String(bbuf,0,hasRead)); } } } }
运行结果:
范例:RandomAccessFile向指定文件追加内容
package com.chengxuyuanzhiliu; import java.io.RandomAccessFile; public class AppendContent { public static void main(String[] args){ try(RandomAccessFile raf = new RandomAccessFile("D:/out.txt", "rw")){ //将记录指针移动到out.txt文件的最后 raf.seek(raf.length()); raf.write("\r\n追加的内容!".getBytes()); }catch (Exception e) { e.printStackTrace(); } } }
运行结果:
范例:实现向指定文件、指定位置插入内容的功能
package com.chengxuyuanzhiliu; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.RandomAccessFile; public class InsertContent { public static void insert(String fileName,long pos,String insertContent) throws IOException{ //创建一个临时文件来保存插入点后的数据 File tmp = File.createTempFile("tmp", null); tmp.deleteOnExit(); try( RandomAccessFile raf = new RandomAccessFile(fileName, "rw"); FileOutputStream tmpOut = new FileOutputStream(tmp); FileInputStream tmpIn = new FileInputStream(tmp) ){ raf.seek(pos); //----下面代码将插入点后的内容读入临时文件中保存---- byte[] bbuf = new byte[64]; //用于保存实际读取的字节数 int hasRead = 0; //使用循环方式读取插入点后的数据 while((hasRead = raf.read(bbuf)) > 0){ tmpOut.write(bbuf, 0, hasRead); } //----下面代码用于插入内容---- //把文件记录指针重新定位到pos位置 raf.seek(pos); //追加需要插入的内容 raf.write(insertContent.getBytes()); //追加临时文件中的内容 while((hasRead = tmpIn.read(bbuf)) > 0){ raf.write(bbuf, 0, hasRead); } } } public static void main(String[] args) throws IOException { insert("D:/Workspaces/Java/Eclipse/JavaIO/src/com/chengxuyuanzhiliu/InsertContent.java", 45, "插入的内容\r\n"); } }
运行结果: