1.创建对象
1)简介
Java提供了一个可以对文件随机访问的操作,访问包括读和写的操作。类名为:RandomAccessFile。该类的读写是基于指针的操作。
RandomAccessFile在对文件进行随机访问操作时有两个模式,分别为只读模式(只读取文件数据) , 和读写模式(对文件数据进行读写)。
(1)只读模式
在创建RandomAccessFile时, 其提供的构造方法要求我们传入访问模式:
---------RandomAccessFile(File file,String mode)
---------RandomAccessFile(String filename,String mode)
其中构造方法的第一个参数是需要访问的文件,而第二个参数则是访问模式:"r" :字符串" r”表示对该文件的访问是只读的。
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
/**
* 从文件中读取字节
*/
public class RAFDemo2 {
public static void main(String[] args) throws IOException {
RandomAccessFile raf = new RandomAccessFile("./raf.dat","r");
/*
int read()
读取一个字节(8位2进制)并以int形式返回,如果返回值为-1
则表示读取到了文件末尾
*/
int d = raf.read();
System.out.println(d);
d = raf.read();
System.out.println(d);
d = raf.read();
System.out.println(d);
d = raf.read();
System.out.println(d);
d = raf.read();
System.out.println(d);
}
}
(2)读写模式
创建一个基于文件访问的读写模式的RandomAccessFile我们只需要在第二个参数中传入”rw" 即可
---RandomAccessFile raf = new RandomAccessFile(file," rw" );
那么这时在使用RandomAccessFile对该文件的访问就是又可读又可写的。
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.Random;
/**
* 随机 访问 文件
* java.io.RandomAccessFile
* RAF是专门用来读写文件数据的API,其基于指针对文件任意位置进行读写
*/
public class RAFDemo1 {
public static void main(String[] args) throws IOException {
/*
RAF常用构造器
RandomAccessFile(String path, String mode)
RandomAcceccFile(File file , String mode)
第一个参数是操作的文件,可以直接给路径也可以给File对象
第二个参数为操作模式:
r:只读模式,仅对文件进行读取操作
rw:对文档既可读又可写
*/
RandomAccessFile raf =new RandomAccessFile("./raf.dat","rw");
/*
void Write(int a)
向文件写入1个字节,写入的是给定的int值所对应的2进制的“低八位
*/
raf.write(17);
raf.write(25);
System.out.println("写出完毕!");
raf.close();
}
}
2.字节数据读写操作
1)write(int b)方法
RandomAccessFile提供了一个可以向文件中写出字节的方法:
--------- void write(int d)
该方法会根据当前指针所在位置处写入一个字节, 是将参数int的”低8位"写出。
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.io.UnsupportedEncodingException;
/**
* 读写字符串操作
*/
public class WriteStringDemo {
public static void main(String[] args) throws IOException {
RandomAccessFile raf = new RandomAccessFile("demo.txt","rw");
String line = "水电费哈利啊剧倪芳 次AV,发酵后我挨罚hi啊哈";
/*
String 提供了将字符串转换为字节的对应方法:
byte[] getByte(String charsetName)
参数为指定的字符集,如果该字符集拼写错误则会抛出异常
UnsupportedEncodingException
*/
/*
将字符串咦UTF-8编码转换为一组字节
UTF-8中编码字节量:
英文占用1字节,中文占用3字节
*/
byte[] data = line.getBytes("UTF-8");
raf.write(data);
System.out.println("写出完毕!");
raf.close();
}
}
2)read()方法
RandomAccessFile提供了一个可以从文件中读取字节的方法:
int read();
该方法会从文件中读取一-个byte(8位)填充到int的低八位,高24位为0,返回值范围正数: 0~ 255,如果返回-1表示读取到了文件末尾!每次读取后自动移动文件指针,准备下次读取。
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
/**
* 读取文本数据
*/
public class ReadStringDemo {
public static void main(String[] args) throws IOException {
//从raf.dat中将文本信息读取出来
RandomAccessFile raf = new RandomAccessFile("raf.dat","r");
//1.从文件中将字节读取出来
byte[] data = new byte[(int)raf.length()];
raf.read(data);
//2将字节还原为字符串
String str = new String(data,"UTF-8");
System.out.println(str);
raf.close();
}
}
3)read(byte[] b)方法
import java.io.IOException;
import java.io.RandomAccessFile;
/**
* 提高每次读写的数据量减少实际读写的次数可以提高读写的效率
* 一次一组字节的读写称为块读写
* RandomAccessFile提供了一次读写一组数据的相应方法
*/
public class CopyDemo2 {
public static void main(String[] args) throws IOException {
RandomAccessFile src = new RandomAccessFile("./Birthday.zip","r");
RandomAccessFile sec = new RandomAccessFile("./生日.zip","rw");
/*
int read(byte[] data)
该方法读取给定的字节数组总长度的字节量,并装入到该数组中返回值为实际读取到的字节量。
如果返回值为-1则表示本次读取是在文件末尾
与int read()方法的区别:
1:一次读取一组字节
2:返回值意义不同,read()方法返回的int值就是实际读取的数据(只不过只有低八位二进制有效},
而read(byte[] data)则是江都区的数据存入给定的数组,返回值仅表示读取到了多少个字节
戴氏相同点是如果返回值我-1都是表示文件末尾
void write(byte[] data)
一次性将给定字节数组中的所有字节写入文件
void write(byte[] data,int offest , int len)
一次性将给定字节数组从下标offest处开始的连续len个字节写出
*/
int len = 0;//用于记录每次实际读取到的字节数
//1GB = 1024MB;1MB = 1024KB;1KB=1024byte
byte[] data = new byte[1024*10];//10kb
long start = System.currentTimeMillis();
while((len = src.read(data))!=-1){
sec.write(data,0,len);
}
long end = System.currentTimeMillis();
System.out.println("复制完毕!耗时为:"+(end-start)+"ms");
src.close();
sec.close();
}
}
4)close()方法
RandomAccessFile在对文件访问的操作全部结束后,要调用close(方法来释放与其关联的所有系统资源。
---------- void close()
RandomAccessFile raf = new RandomAccessFile(file," rw" );..//读写操作
raf.close();//访问完毕后要关闭以释放系统资源。
3.文件指针操作
1)getFilePoint()方法
2)seek()方法
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
/**
* 读写基本类型数据以及RAF基于指针的读写操作
*/
public class RAFdemo3 {
public static void main(String[] args) throws IOException {
/*
注:
data 数据的意思
文件的后缀名实际上是window操作系统的习惯,用以让windows双击某个文件是使用对应的程序打开,
一次我们一般用后缀判别文件的类型,比如常见的有:exe,txt,jpg等等;
但是后缀可以自创,自己清楚该文件数据是什么即可。
*/
RandomAccessFile raf = new RandomAccessFile("data.txt","rw");
long pos = raf.getFilePointer();
//写入一个int最大值
int imax = Integer.MAX_VALUE;
System.out.println("pos:"+raf.getFilePointer());
raf.write(imax>>>24);
System.out.println("pos:"+raf.getFilePointer());
raf.write(imax>>>16);
System.out.println("pos:"+raf.getFilePointer());
raf.write(imax>>>8);
System.out.println("pos:"+raf.getFilePointer());
raf.write(imax);
System.out.println("pos:"+raf.getFilePointer());
/*
RAF提供了方便写出基本类型数据的方法
*/
//连续写出4个字节,将int值写出,等同于上面的操作
raf.writeInt(imax);
System.out.println("pos:"+raf.getFilePointer());
//连续写出8个字节,将long对应的二进制写出
raf.writeLong(123L);
System.out.println("pos:"+raf.getFilePointer());
raf.writeDouble(123.123);
System.out.println("pos:"+raf.getFilePointer());
System.out.println("写出完毕!");
/*
void seek(long pos)
将指针移动到指定位置
*/
/*
RAF提供的读取基本啥类型的相关方法如:readInt,ReadLong等
这些方法内部会连续有读取若干字节来还原对应的基本类型,如果
在连续读取字节的过程中读到了文件末尾(但是应当读取字节数还
没有到达,比如int应当连续读取4个字符,但是在这这个过程中就
读取到了文件末尾)此时会抛出EOFExceptiuon
EOF:end of file 文件末尾异常
*/
raf.seek(0);//将指针移动到文件最开始
//连续读取4个字节并还原为对应的int值
int d = raf.readInt();
System.out.println(d);
System.out.println("pos:"+raf.getFilePointer());
//读取long
//1先将指针移动到long的开始位置
raf.seek(8);
long l = raf.readLong();
System.out.println(l);
System.out.println("pos:"+raf.getFilePointer());
//读取double
raf.seek(16);
double a = raf.readDouble();
System.out.println(a);
//将long值改为5566
//1将指针移动到long的第一个字节位置
raf.seek(8);
//2重新写入long值(8字节)覆盖原内容
raf.writeLong(5566);
raf.seek(8);
l = raf.readLong();
System.out.println(l);
raf.close();
}
}