packagecom.company;
importjava.io.*;
public classMain {
public static voidmain(String[] args) throwsIOException{
// write your code hereFileManage fileManage = newFileManage("/home/wu/a.txt");
fileManage.append("aple",12);
fileManage.append("teststring",454);
fileManage.seek(2);
fileManage.close();
}
}
classFileManage{
privateFile file;
privateRandomAccessFile read;
publicFileManage(String filepath) {
try{
file= newFile(filepath);
read= newRandomAccessFile(file,"rw");
}catch(IOException ex) { System.out.println(ex.getMessage()); }
}
public voidclose(){
try{
read.close();
}catch(IOException ex){System.out.println(ex.getMessage());}}
public voidappend(String name,floatprice){
intnamePosition, pricePosition;
byte[] bytesName = name.getBytes();
byte[] bytesPrice = getByteFromFloat(price);
try{
namePosition = (int)(read.length() + bytesName.length+ 8); /*跳过两个位置的长度*/pricePosition = bytesPrice.length+ namePosition;
byte[] bytesNamePosition = getByteFromInt(namePosition);
byte[] bytesPricePosition = getByteFromInt(pricePosition);
read.seek(read.length());
/*依次写入数据*/for(bytei : bytesNamePosition) read.writeByte(i);
for(bytei : bytesPricePosition) read.writeByte(i);
for(bytei : bytesName) read.writeByte(i);
for(bytei : bytesPrice) read.writeByte(i);
}catch(IOException ex){ System.out.println(ex); }
}
private intgetPosition(intp){ //接受一个位置参数 读取位置信息byte[] bytes = new byte[4];
intposition;
try{
read.seek(p);
for(inti=0; i<4; i++) bytes[i] = read.readByte();
position = getInt(bytes);
returnposition;
}catch(IOException ex){ System.out.println(ex.getMessage()); }
System.exit(-1);
return-1;
}
public voidseek(intn){
intnamePosition, pricePosition; //遍历中的名字 价格位置信息inttemp = 8;
namePosition = getPosition(0); //取得第一个存放name的位置pricePosition = getPosition(4);//取得第一个存放price的位置intcount = 0;
while(count < n-1){ //取n的前一个(n-1)temp = pricePosition; //保存开始取得下一个信息的起始位置 在取得name循环时利用pricePosition = getPosition(pricePosition+4); //跳过namePosition直接取得pricePositionnamePosition = getPosition(temp); //取得namePositioncount++;
}
if(n > 1) temp = temp+8; //如果取的不是第一个跳过namePosition pricePositionbyte[] bytesName = new byte[namePosition-temp];
byte[] bytesPrice = new byte[4];
try{
read.seek(temp); //定位到name的起始位置for(inti=temp,j=0; i
for(inti=namePosition,j=0; i
System.out.println("name :"+newString(bytesName)+ " price :"+getFloat(bytesPrice));
}catch(IOException ex){ System.out.println(ex.getMessage()); }
}
/* 以下函数将基本数据类型转换成字节数组和字节数组转换成基本数据类型*/
/* 出自http://www.jianshu.com/p/35b69f1acdd9 */
public static byte[] getByteFromInt(intdata){
byte[] temp=new byte[4];
temp[0]=(byte)(0xFF&(data));
temp[1]=(byte)(0xFF&(data>>8));
temp[2]=(byte)(0xFF&(data>>16));
temp[3]=(byte)(0xFF&(data>>24));
returntemp;
}
public static intgetInt(byte[] bytes) {
return(0xff& bytes[0]) | (0xff00& (bytes[1] << 8)) | (0xff0000& (bytes[2] << 16))
| (0xff000000& (bytes[3] << 24));
}
public static floatgetFloat(byte[] bytes){
inttemp=getInt(bytes);
returnFloat.intBitsToFloat(temp);
}
public static byte[] getByteFromFloat(floatdata){
byte[] temp=new byte[4];
inttempInt=Float.floatToIntBits(data);
temp[0]=(byte)(0xFF&(tempInt));
temp[1]=(byte)(0xFF&(tempInt>>8));
temp[2]=(byte)(0xFF&(tempInt>>16));
temp[3]=(byte)(0xFF&(tempInt>>24));
returntemp;
}
}
程序设计思路是:主要有append,seek函数
append函数:
1.先把要写入的数据转换成字节数组(统一转换成一种数据类型)得到各自的长度。
2.再用两个int记录名字的位置和价格的位置,再把两个int转换成字节数组。
3.先写入两个int数据,再写入名字的字节数组和价格的字节数组。
如:
name: teststring price: 12
bytesName = name.getBytes(); bytesPrice = getByteFromFloat(price);
name的字节数组的长度为10,所以得到变量namePosition为8+10 = 18(加八是跳过两个记录位置int的数据)。
之后变量pricePosition为18+4 = 22(价格的数据类型为float,float转换成字节数组的长度为4)
依次写入数据:
18
22
bytesName
bytesPrice
18 22
seek函数:
接受一个要查询第几个的参数n
1.先取得第一个存放name的位置,第一个存放price的位置
2.在循环中找到n的前n-1个,再取得第n个的namePosition,pricePosition。
3.声明两个字节数组,读取bytesName,bytesPrice。得到查询结果。
如:seek(2) 假设有两个name: teststring price: 12
18
22
bytesName
bytesPrice
40
44
bytesName
bytesPrice
18 22 40 44
namePosition = 18 pricePosition = 22
用RandomAccessFile的seek函数跳到seek(22) 此时变量temp = pricePositon = 22
再读取40和44 得到namePosition = 40 pricePosition = 44 循环结束
得到bytesName的长度为40-(temp+8) = 10 (加八是跳过两个int字节数组)
同理得bytesPrice的长度为44 - 40 = 4
for(inti=temp,j=0; i
bytesName[j] = read.readByte();
for(inti=namePosition,j=0; i
bytesPrice[j] = read.readByte();
再利用String()的构造函数和getFloat(bytesPrice)函数 输出信息