RandomAccessFile就像数据库一样,是将数据一条一条的写入的,而这些数据必须是类对象,不能是基本类型数据,因为该类对象要写两个方法write和read用来将对象写入RandomAccessFile,这两个方法也不是继承于谁,可以起别的名字,调用的时候也是自己调用。
public class Student extends IOBaseS{ private long id; private String name; private int age; private double height; public Student() { } public Student(long id, String name, int age, double height) { super(); this.id = id; this.name = name; this.age = age; this.height = height; } public void write(RandomAccessFile raf) throws IOException { raf.writeLong(id); raf.writeUTF(name);// 采用UTF的编码方式写入字符串 raf.writeInt(age); raf.writeDouble(height); } /** * 要严格按照写入顺序读取,这也是ORM的意义 * * @param raf * @throws IOException */ public void read(RandomAccessFile raf) throws IOException { this.id = raf.readLong(); this.name = raf.readUTF(); this.age = raf.readInt(); this.height = raf.readDouble(); } }按照类的结构,将字段按顺序写入文件的任意位置,读取的时候也要按照相同的顺序读出。
RandomAccessFile 追加内容
追加的时候要使用seek方法,将光标定位到文件末尾,如果不重新定位,默认从起点开始写入,就会覆盖原有数据。
RandomAccessFile 在任意位置插入数据
@Test public void insert() { Student Hudson = new Student(1005, "Hudson", 45, 1.76d); try { insert(root + "/access", 26, Hudson); } catch (IOException e) { e.printStackTrace(); } } /** * 在RandomAccessFile指定位置插入数据,先将位置后面的数据放入缓冲区,插入数据以后再将其写回来。 * * @param file * 能找到该文件的路径,是字符串类型 * @param position * 其实外部调用的时候能找到这个位置比较难,因为不确定数据长度是多少,弄不好就会将数据拆分引起混乱。 * @param content */ public void insert(String file, long position, Student s) throws IOException { /** * 创建一个临时文件 * * 在使用完以后就将其删除 */ File tempFile = File.createTempFile("temp", null); tempFile.deleteOnExit(); FileOutputStream fos = new FileOutputStream("temp"); /** * 将插入位置后面的数据缓存到临时文件 */ RandomAccessFile raf = new RandomAccessFile(file, "rw"); raf.seek(position); byte[] buffer = new byte[20]; while (raf.read(buffer) > -1) { fos.write(buffer); } raf.seek(position); /** * 向RandomAccessFile写入插入内容 */ s.write(raf); /** * 从临时文件中写回缓存数据到RandomAccessFile */ FileInputStream fis = new FileInputStream("temp"); while (fis.read(buffer) > -1) { raf.write(buffer); } fos.close(); fis.close(); raf.close(); tempFile.delete();//删除临时文件tempFile }插入数据的时候,RandomAccessFile并没有提供相关的方法,由于在旧的位置写入数据会覆盖原有数据,所以我们要将插入位置后面的数据缓存到一个临时文件中,插入数据以后再将临时文件的内容接着被插入的数据后面。
JUnit生命周期
完整JUnit执行顺序:
/@BeforeClass –> /@Before –> /@Test –> /@After –> /@AfterClass
/@BeforeClass和/@AfterClass只执行一次,且必须为static void
/@Ignore 在执行整个类的时候会跳过该方法
下面我们定义一个完整测试流程:先初始化一个空白文件,然后添加两行数据Jhon和Jack,然后在他俩中间插入Hudson,最后读出该文件数据,验证结果输出为:
/** * 输出: * 17:10:31[testWrite2RAFile]: 0 17:10:31[testWrite2RAFile]: 26 * 17:10:31[testWrite2RAFile]: 52 17:10:31[testReadRAFile]: 94 * 17:10:31[testReadRAFile]: id:1001 name:Jhon age:26 height:1.85 * 17:10:31[testReadRAFile]: id:1005 name:Hudson age:45 height:1.76 * 17:10:31[testReadRAFile]: id:1002 name:Jack age:25 height:1.75 */ 二、DataOutputStream / DataInputStream