黑马程序员——Java IO—RandomAccessFile

来源:互联网 发布:mac快速接入 编辑:程序博客网 时间:2024/05/01 06:12

---------------------- ASP.Net+Unity开发、.Net培训、期待与您交流! ----------------------


public class RandomAccessFile extends Object implements DataOutput, DataInput, Closeable

RandomAccessFile属于java的输入/输出流体系,但是它与输入输出流体系中的其它流没有任何关系(除实现了DataInput、DataOutput接口外,DataInputStream、DataOutputStream也实现了这2个接口)。它直接继承自Object;它不使用InputStream和OutputStream类体系中已经存在的任何功能;它是一个完全独立的类,所有方法(绝大多数都只属于它自己)都是从零开始写的。

RandomAccessFile兼具输入和输出功能,它既拥有从文件中读取数据的基本方法(read()、read(byte[] b)、read(byte[] b, int off, int len)),又拥有向文件中写数据的基本方法(write(int b)、write(byte[] b)、write(byte[] b, int off, int len))。由于它实现了DataInput和DataOutput接口,所以它也拥有从文件读取或向文件写入基本数据类型、UTF格式字符串的方法。

RandomAccessFile对象中也包含了一个记录指针,用以表示当前读写处的位置,当程序新创建一个RandomAccessFile对象时,该对象的文件记录指针位于文件头(也就是0处),当都/写了n个字节后,记录指针会向后移动n个字节。RandomAccessFile可以自由移动记录指针,既可以向前移动,也可以向后移动:long getFilePointer()方法返回文件记录指针的当前位置;void seek(long pos)方法将文件记录指针定位到pos位置。正式基于以上特性,RandomAccessFile可以自由访问文件的任意位置,比如我们只想读取文件的部分内容,而不是把文件从头读到尾或者我们想向文件的中间添加数据,这些需求都可以使用RandomAccessFile来完成。

RandomAccessFile可以随意定位文件记录指针的位置,所以它可以先将指针定位至文件的中间,然后再文件的中间插入数据。但是在这种情况下必须要注意,如果此时直接输出要添加的内容,那么新添加的内容会将后面原有的内容覆盖掉。如果想在不覆盖原有内容的情况下向文件的中间部分添加新内容,必须先把插入点后面的内容读入缓冲区,等把需要插入的内容写入文件后,再将缓冲区中的内容追加到文件后面。

RandomAccessFile的构造方法

public RandomAccessFile(String name, String mode)                 throws FileNotFoundExceptionpublic RandomAccessFile(File file, String mode)                 throws FileNotFoundException

name 和 file 都代表被读写的文件。
mode是String类型的,有4中取值:"r"、"rw"、"rws"、"rwd"。
"r":以只读方式打开指定文件。如果试图对该RandomAccessFile执行写入方法,都将引发IOException异常。
"rw":以读写方式打开指定文件。如果该文件已存在,则使用已存在的文件;如果该文件不存在,则尝试创建该文件。
关于"rws"、"rwd"的使用还不太明白,等以后再补充与它们有关的内容。
RandomAccessFile没有提供只写"w"的模式。


下面对RandomAccessFile的方法做一个简单的分类。
read方法:
3个基本的read方法(read()、read(byte[] b)、read(byte[] b, int off, int len))
2个Fully方法(readFully(byte[] b)、readFully(byte[] b, int off, int len))
8个读取基本数据类型的方法(byte、short、int、long、float、double、char、boolean)
2个读取unsigned数据的方法(readUnsignedByte()、readUnsignedShort())
2个读取String的方法(readLine()、readUTF())


write方法:
3个基本的write方法(write(int b)、write(byte[] b)、write(byte[] b, int off, int len))
8个写基本数据类型的方法 + 2个(writeBytes(String s)、writeChars(String s))
1个写String的方法(writeUTF(String str))


与文件记录指针相关的方法:

public long getFilePointer() throws IOExceptionpublic void seek(long pos) throws IOException

其他方法:

public long length() throws IOExceptionpublic void close() throws IOException

小示例:
该小示例包括以下内容:
1、使用RandomAccessFile创建一个文件并写入部分数据
2、使用RandomAccesssFile读取文件的后半部分内容(即跳过前面的一部分内容,直接从中间开始读)
3、使用RandomAccessFile向文件末尾追加内容
4、在不覆盖原有内容的情况下,使用RandomAccessFile向文件的中间插入数据

package org.lgy.study.io;import java.io.RandomAccessFile;import java.io.File;import java.io.FileNotFoundException;import java.io.IOException;import java.io.FileInputStream;import java.io.FileOutputStream;/* javac -d classes "src/org/lgy/study/io/RandomAccessFileTest.java"java org.lgy.study.io.RandomAccessFileTest */public class RandomAccessFileTest{public static void main(String[] args){method1();method2();method3();method4();}// 使用RandomAccessFile创建一个文件并写入部分数据public static void method1(){File rootFile = new File("./src/org/lgy/study/io");try(RandomAccessFile randFile = new RandomAccessFile(new File(rootFile, "ran_acc_file.txt"), "rw");){// 获取文件记录指针的初始位置sop("文件记录指针的初始位置:pos = 0 " + randFile.getFilePointer());randFile.write(1);  // 写入一个byte,值为1,占1个字节sop("pos = 1 " + randFile.getFilePointer());randFile.writeByte(2);  // 写入一个byte,值为2,占1个字节sop("pos = 2 " + randFile.getFilePointer());randFile.writeShort(3);  // 写入一个short,值为3,占2个字节sop("pos = 4 " + randFile.getFilePointer());randFile.writeInt(4);  // 写入一个int,值为4,占4个字节sop("pos = 8 " + randFile.getFilePointer());randFile.writeLong(5L);  // 写入一个long,值为5,占8个字节sop("pos = 16 " + randFile.getFilePointer());randFile.writeFloat(0.1F); // 写入一个float,值为0.1,占4个字节sop("pos = 20 " + randFile.getFilePointer());randFile.writeDouble(0.2D); // 写入一个double,值为0.2,占8个字节sop("pos = 28 " + randFile.getFilePointer());randFile.writeChar('A');  // 写入一个char,值为‘A’,占2个字节sop("pos = 30 " + randFile.getFilePointer());randFile.writeUTF("你好啊"); // 写入一个String,值为"你好",占多少字节是不确定的,为了能够读取出写入的字符串,系统会自动添加边界信息。sop("pos = 36 " + randFile.getFilePointer());sop("文件长度: 36 " + randFile.length());}catch(FileNotFoundException e){e.printStackTrace();}catch(IOException e){e.printStackTrace();}}// 使用RandomAccesssFile读取文件的后半部分内容(即跳过前面的一部分内容,直接从中间开始读)public static void method2(){File rootFile = new File("./src/org/lgy/study/io");try(// 以只读的方式打开文件RandomAccessFile randFile = new RandomAccessFile(new File(rootFile, "ran_acc_file.txt"), "r");){sop("文件记录指针的初始位置 pos = " + randFile.getFilePointer());randFile.seek(16);  // 将文件记录指针定位到第16个字节后sop("重定位后文件记录指针的位置 pos = " + randFile.getFilePointer());float f = randFile.readFloat(); // 读取一个float,连续读取4个字节sop("f = " + f);double d = randFile.readDouble();  // 读取一个double,连续读取8个字节sop("d = " + d);char ch = randFile.readChar();  // 读取一个char,连续读取2个字节sop("ch = " + ch);String str = randFile.readUTF(); // 读取一个String,根据系统预定义的边界sop("str = " + str);}catch(FileNotFoundException e){e.printStackTrace();}catch(IOException e){e.printStackTrace();}}// 使用RandomAccessFile向文件末尾追加内容public static void method3(){File rootFile = new File("./src/org/lgy/study/io");try(// 以读写方式打开文件RandomAccessFile randFile = new RandomAccessFile(new File(rootFile, "ran_acc_file.txt"), "rw");){// 因为新创建的RadomAccessFile对象的文件记录指针位于文件头,所以如果想向文件尾部追加数据必须将文件记录指针定位到文件尾部sop("文件记录指针的初始位置 pos = " + randFile.getFilePointer());randFile.seek(randFile.length());  // 将文件记录指针定位到文件尾部sop("重定位后文件记录指针的位置 pos = " + randFile.getFilePointer());randFile.writeUTF("再见");}catch(FileNotFoundException e){e.printStackTrace();}catch(IOException e){e.printStackTrace();}// 下面读取出追加的数据try(RandomAccessFile randFile = new RandomAccessFile(new File(rootFile, "ran_acc_file.txt"), "r");){randFile.seek(41);  // 将文件记录指针定位到原来文件的尾部String str = randFile.readUTF();sop("追加的数据是:" + str);}catch(FileNotFoundException e){e.printStackTrace();}catch(IOException e){e.printStackTrace();}}// 在不覆盖原有内容的情况下,使用RandomAccessFile向文件的中间插入数据public static void method4(){RandomAccessFile randFile = null;FileInputStream fis = null;FileOutputStream fos = null;File rootFile = new File("./src/org/lgy/study/io");try{File tempFile = File.createTempFile("temp", "temp", rootFile);tempFile.deleteOnExit();Thread.sleep(5000);randFile = new RandomAccessFile(new File(rootFile, "ran_acc_file.txt"), "rw");fos = new FileOutputStream(tempFile);fis = new FileInputStream(tempFile);sop("文件记录指针的初始位置 pos = " + randFile.getFilePointer());randFile.seek(16);  //  在原来的long型数据后添加一个UTF字符串sop("重定位后指针的位置 pos = " + randFile.getFilePointer());byte[] buf = new byte[512];int size = -1;while((size = randFile.read(buf)) != -1){fos.write(buf, 0, size);}sop("数据保存至临时文件成功,当前记录指针的位置 pos = " + randFile.getFilePointer());randFile.seek(16);sop("重定位后记录指针的位置 pos = " + randFile.getFilePointer());randFile.writeUTF("呵呵哈哈哦哦");while((size = fis.read(buf)) != -1){randFile.write(buf, 0, size);}}catch(FileNotFoundException e){e.printStackTrace();}catch(IOException e){e.printStackTrace();}catch(InterruptedException e){e.printStackTrace();}finally{if(randFile != null){try{randFile.close();}catch(IOException e){e.printStackTrace();}}if(fis != null){try{fis.close();}catch(IOException e){e.printStackTrace();}}if(fos != null){try{fos.close();}catch(IOException e){e.printStackTrace();}}}// 下面取出插入数据后文件的所有内容try{randFile = new RandomAccessFile(new File(rootFile, "ran_acc_file.txt"), "r");sop("插入数据后的文件内容如下:");sop(randFile.read());  // 1sop(randFile.readByte());  // 2sop(randFile.readShort());  // 3sop(randFile.readInt());  // 4sop(randFile.readLong());  // 5sop(randFile.readUTF());  // 这就是插入的数据,UTF字符串"呵呵哈哈哦哦"sop(randFile.readFloat());  // 0.1sop(randFile.readDouble());  // 0.2sop(randFile.readChar());  // Asop(randFile.readUTF());  // "你好啊"sop(randFile.readUTF());  // "再见"}catch(FileNotFoundException e){e.printStackTrace();}catch(IOException e){e.printStackTrace();}finally{if(randFile != null){try{randFile.close();}catch(IOException e){e.printStackTrace();}}}}public static void sop(Object obj){System.out.println(obj);}}/* method1的运行结果:文件记录指针的初始位置:pos = 0 0pos = 1 1pos = 2 2pos = 4 4pos = 8 8pos = 16 16pos = 20 20pos = 28 28pos = 30 30pos = 36 41文件长度: 36 41method2的运行结果:文件记录指针的初始位置 pos = 0重定位后文件记录指针的位置 pos = 16f = 0.1d = 0.2ch = Astr = 你好啊method3的运行结果:文件记录指针的初始位置 pos = 0重定位后文件记录指针的位置 pos = 41追加的数据是:再见method4的执行结果:文件记录指针的初始位置 pos = 0重定位后指针的位置 pos = 16数据保存至临时文件成功,当前记录指针的位置 pos = 49重定位后记录指针的位置 pos = 16插入数据后的文件内容如下:12345呵呵哈哈哦哦0.10.2A你好啊再见 */


---------------------- ASP.Net+Unity开发、.Net培训、期待与您交流! ----------------------
0 0
原创粉丝点击