java编程笔记16 随机访问文件类RandomAccessFile

文件的随机访问主要是通过RandomAccessFile来完成,它使用seek()方法从文件中的一个记录移动到下一个记录进行读或者写,而不需要知道总共多少个记录。它不需要把所有的记录全部装进内存再进行读写,对于访问大文件来说,这是一种高效的选择。

构造函数:两种方法来制定对应的文件:字符串路径和File

构造方法摘要
RandomAccessFile(File file, String mode)
          创建从中读取和向其中写入(可选)的随机访问文件流,该文件由 File 参数指定。
RandomAccessFile(String name, String mode)
          创建从中读取和向其中写入(可选)的随机访问文件流,该文件具有指定名称。

常用方法:

方法摘要
 voidclose()
          关闭此随机访问文件流并释放与该流关联的所有系统资源。
 FileChannelgetChannel()
          返回与此文件关联的唯一 FileChannel 对象。
 FileDescriptorgetFD()
          返回与此流关联的不透明文件描述符对象。
 longgetFilePointer()
          返回此文件中的当前偏移量。
 longlength()
          返回此文件的长度。
 intread()
          从此文件中读取一个数据字节。
 intread(byte[] b)
          将最多 b.length 个数据字节从此文件读入 byte 数组。
 intread(byte[] b, int off, int len)
          将最多 len 个数据字节从此文件读入 byte 数组。
 booleanreadBoolean()
          从此文件读取一个 boolean
 bytereadByte()
          从此文件读取一个有符号的八位值。
 charreadChar()
          从此文件读取一个字符。
 doublereadDouble()
          从此文件读取一个 double
 floatreadFloat()
          从此文件读取一个 float
 voidreadFully(byte[] b)
          将 b.length 个字节从此文件读入 byte 数组,并从当前文件指针开始。
 voidreadFully(byte[] b, int off, int len)
          将正好 len 个字节从此文件读入 byte 数组,并从当前文件指针开始。
 intreadInt()
          从此文件读取一个有符号的 32 位整数。
 StringreadLine()
          从此文件读取文本的下一行。
 longreadLong()
          从此文件读取一个有符号的 64 位整数。
 shortreadShort()
          从此文件读取一个有符号的 16 位数。
 intreadUnsignedByte()
          从此文件读取一个无符号的八位数。
 intreadUnsignedShort()
          从此文件读取一个无符号的 16 位数。
 StringreadUTF()
          从此文件读取一个字符串。
 voidseek(long pos)
          设置到此文件开头测量到的文件指针偏移量,在该位置发生下一个读取或写入操作。
 voidsetLength(long newLength)
          设置此文件的长度。
 intskipBytes(int n)
          尝试跳过输入的 n 个字节以丢弃跳过的字节。
 voidwrite(byte[] b)
          将 b.length 个字节从指定 byte 数组写入到此文件,并从当前文件指针开始。
 voidwrite(byte[] b, int off, int len)
          将 len 个字节从指定 byte 数组写入到此文件,并从偏移量 off 处开始。
 voidwrite(int b)
          向此文件写入指定的字节。
 voidwriteBoolean(boolean v)
          按单字节值将 boolean 写入该文件。
 voidwriteByte(int v)
          按单字节值将 byte 写入该文件。
 voidwriteBytes(String s)
          按字节序列将该字符串写入该文件。
 voidwriteChar(int v)
          按双字节值将 char 写入该文件,先写高字节。
 voidwriteChars(String s)
          按字符序列将一个字符串写入该文件。
 voidwriteDouble(double v)
          使用 Double 类中的 doubleToLongBits 方法将双精度参数转换为一个 long,然后按八字节数量将该 long 值写入该文件,先定高字节。
 voidwriteFloat(float v)
          使用 Float 类中的 floatToIntBits 方法将浮点参数转换为一个 int,然后按四字节数量将该 int 值写入该文件,先写高字节。
 voidwriteInt(int v)
          按四个字节将 int 写入该文件,先写高字节。
 voidwriteLong(long v)
          按八个字节将 long 写入该文件,先写高字节。
 voidwriteShort(int v)
          按两个字节将 short 写入该文件,先写高字节。
 voidwriteUTF(String str)
          使用 modified UTF-8 编码以与机器无关的方式将一个字符串写入该文件。

测试程序:将4条person数据按照一定的格式(各字段定长写入到文件),然后随机遍历整个文件,输出所有的记录。然后找到包含关键字的的记录。

package FileOperation;

import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.ArrayList;
import java.util.List;

public class FileRandomAccess {
	
	/** 姓名在文件中的长度 */
	public static final int NAME_LENGTH = 100;
	/** 年龄在文件中的长度 */
	public static final int INT_LENGTH = 8;
	public static final int DESCRIPTION_LENGTH = 200;
	/** 每条 Person 记录在文件中的长度 */
	public static final int PERSON_LENGTH = NAME_LENGTH + INT_LENGTH + DESCRIPTION_LENGTH;

	//Person内部类
	static class Person{
		
		public String name;
		public int age;
		public String description;
		
		public Person(String name, int age, String description){
			this.name = name;
			this.age = age;
			this.description = description;
		}
		
		public String toString(){
			return "Person[name=\"" + name + "\", age=\"" + age + "\", description=\"" + description + "\"]";
		}		
	}

	
	//定义一个Person类型的数组
	static Person[] person = new Person[] { 
						new Person("杜甫", 45, "唐朝现实主义诗人"),
						new Person("爱因斯坦", 20, "伟大的物理学家,提出相对论理论。"), 
						new Person("李白", 20, "唐朝浪漫主义诗人"), 
						new Person("曹雪芹", 47, "《红楼梦》作者"), 
			};
	
	
	//main函数
	public static void main(String[] args) throws IOException{
		
		//构造一个随机访问类的file对象
		RandomAccessFile file = new RandomAccessFile("C:\\person.dat", "rw");
		
		// 初始化数据 根据初始化数据设置文件长度
		file.setLength(person.length * PERSON_LENGTH);
		for(int i=0; i<person.length; i++){
			writePerson(file, person[i]);//调用writePerson
		}
		
		System.out.println("\r\n列出文件中所有的数据:");
		Person[] allPersons = listAllPerson(file);//调用listAllPerson返回一个person数组
		for(int i=0; i<allPersons.length; i++){
			System.out.println(allPersons[i]);
		}
		
		
		System.out.println("\r\n在文件中查找关键字 雪,结果如下:");
		
		Person p = findPerson(file, "雪");//调用findPerson查找file里的keyword
		
		System.out.println("找到结果:" + p);
		
		file.close();
		
	}
	
	
	// 写 String 类型数据,要注意写String和写int的区别,
	public static void writeString(RandomAccessFile file, String name, int fieldLength) throws IOException{
		file.writeUTF(name);
		int length = name.getBytes("UTF-8").length;
		file.skipBytes(fieldLength - length);//跳过没有用完的字节,保持对齐
	}
	
	
	// 写 int 类型数据
	public static void writeInt(RandomAccessFile file, int age) throws IOException{
		file.writeInt(age);
	}
	
	
	//写person对象(写 String,写 int )
	public static void writePerson(RandomAccessFile file, Person person) throws IOException{
		writeString(file, person.name, NAME_LENGTH);
		writeInt(file, person.age);
		writeString(file, person.description, DESCRIPTION_LENGTH);
	}
	
	
	// 读 String 类型数据
	public static String readString(RandomAccessFile file, int fieldLength) throws IOException{
		String name = file.readUTF();
		int length = name.getBytes("UTF-8").length;
		file.skipBytes(fieldLength - length);
		return name;
	}
	
	
	// 读 int 类型数据
	public static int readInt(RandomAccessFile file) throws IOException{
		return file.readInt();
	}
	
	
	//读person对象(读 String,读 int)
	public static Person readPerson(RandomAccessFile file) throws IOException {
		
		// 找到文件头了
		if(file.getFilePointer() >= file.length()){
			return null;
		}
		
		return new Person(
				readString(file, NAME_LENGTH), 	// name
				readInt(file), 	// age
				readString(file, DESCRIPTION_LENGTH)	// description
				);
	}
	
	
	
	// 列出数据文件中的所有的数据
	public static Person[] listAllPerson(RandomAccessFile file) throws IOException {
		List list = new ArrayList();
		file.seek(0);

		while(true){
			Person person = readPerson(file);
			if(person == null)
				break;
			list.add(person);
		}
		Person[] person = new Person[list.size()];
		list.toArray(person);
		return person;
	}
	
	
	// 查找符合条件的数据
	public static Person findPerson(RandomAccessFile file, String keyword) throws IOException {
		// 从开始寻找记录
		file.seek(0);
		while(true){
			Person person = readPerson(file);//每次读一个person,注意每次seek都要往后移动
			if(person == null)
				break;
			if(person.name.contains(keyword)){
				return person;
			}
		}
		return null;
	}
	
}

运行结果:


列出文件中所有的数据:
Person[name="杜甫", age="45", description="唐朝现实主义诗人"]
Person[name="爱因斯坦", age="20", description="伟大的物理学家,提出相对论理论。"]
Person[name="李白", age="20", description="唐朝浪漫主义诗人"]
Person[name="曹雪芹", age="47", description="《红楼梦》作者"]

在文件中查找关键字 雪,结果如下:
找到结果:Person[name="曹雪芹", age="47", description="《红楼梦》作者"]

转载于:https://www.cnblogs.com/jmzz/archive/2011/03/15/1985317.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值