java.io.RandomAccessFile:专门用来读写文件数据的类,其读写是基于指针进行的,即RAF总是在指针指向位置读取或者写出字节。
RAF有两种常用的模式:
* r:只读模式,只能读取文件数据,不可以做写操作。
* rw:读写模式,即可读也可写。
1.写出数据(一个字节):void write(int d)
package raf;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
public class RandomAccessFileDemo {
public static void main(String[] args) throws IOException {
/*
* 对项目目录下的文件test.dat文件进行读写操作
*
* RandomAccessFile(String path, String mode)
* RandomAccessFile(File file, String mode)
*/
RandomAccessFile raf
= new RandomAccessFile("test.dat", "rw");
System.out.println("raf已创建!");
/*
* void write(int d)
* 该方法可以向文件中写入一个字节,写入的是
* 给定的int值所对应的2进制的"低八位".
* vvvvvvvv
* 00000000 00000000 00000001 00000001
*/
raf.write(1);
System.out.println("写出完毕!");
raf.close();
}
}
2.读取数据(一个字节):int read()
package raf;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
/**
* 从文件中读取一个字节
* @author adminitartor
*/
public class ReadDemo {
public static void main(String[] args) throws IOException {
RandomAccessFile raf = new RandomAccessFile("test.dat", "r");
/*
* int read()
* 从文件中读取1个字节,并以int形式返回。若返回
* 值为-1,则表示文件读取到末尾了
* 00000000 00000000 00000000 00000001
*/
int d = raf.read();
System.out.println(d);
d = raf.read();
System.out.println(d);
raf.close();
}
}
3.demo——文件复制(随机读写方式)
package raf;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
/**
* 文件复制操作
* @author adminitartor
*/
public class CopyDemo {
public static void main(String[] args) throws IOException {
/*
* 1:创建一个RAF用于读取原文件
* 2:创建一个RAF用于写入复制文件
* 3:循环从原文件读取每一个字节并写入到复制文件
* 中完成copy工作
*/
//1
RandomAccessFile src
= new RandomAccessFile("img.jpg", "r");
//2
RandomAccessFile desc
= new RandomAccessFile("img_cp.jpg","rw");
//3
int d = -1;
while((d = src.read())!=-1){
desc.write(d);
}
System.out.println("复制完毕!");
src.close();
desc.close();
}
}
4.demo——文件复制(块读写方式)
若想提高读写效率,可以通过提高每次实际读写的数据量减少实际读写次数来达到。
* 单字节读写称为——随机读写方式
* 一次读写一组字节称为——块读写方式
package raf;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
public class CopyDemo2 {
public static void main(String[] args) throws IOException {
//1
RandomAccessFile src
= new RandomAccessFile("movie.avi", "r");
//2
RandomAccessFile desc
= new RandomAccessFile("movie_cp2.avi","rw");
/*
* RAF提供的块读写方法:
* int read(byte[] data)
* 一次性从文件中读取给定的数组长度的字节量,并
* 存入到该数组中,返回值为实际读取到的字节量。
* 若返回值为-1,表示本次没有读取到任何数据(实际
* 是已经是文件末尾了)
*
* void write(byte[] data)
* 一次性将给定的字节数组中所有字节写出
*
* void write(byte[] data,int index,int len)
* 一次性将给定的字节数组中index处开始的连续
* len个字节写出
*/
int len = -1;//表示每次实际读取到的字节量
byte[] data = new byte[1024*10];//10k
long start = System.currentTimeMillis();
while((len = src.read(data))!=-1){
desc.write(data,0,len);
}
long end = System.currentTimeMillis();
System.out.println("复制完毕!耗时:"+(end-start)+"ms");
src.close();
desc.close();
}
}
5.RAF基于指针的读写操作以及RAF读写基本类型数据的操作
package raf;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
public class RandomAccessFileDemo2 {
public static void main(String[] args) throws IOException {
RandomAccessFile raf
= new RandomAccessFile("raf.dat", "rw");
/*
* 获取raf当前指针位置,RAF刚创建时是在文件最
* 开始,对应的位置为0.
*/
long pos = raf.getFilePointer();
System.out.println("pos:"+pos);
/*
* 向文件中写入一个int最大值
* vvvvvvvv
* 01111111 11111111 11111111 11111111
*
* max>>>24
* 00000000 00000000 00000000 01111111
*/
int max = Integer.MAX_VALUE;
raf.write(max>>>24);
System.out.println("pos:"+raf.getFilePointer());
raf.write(max>>>16);
raf.write(max>>>8);
raf.write(max);
System.out.println("pos:"+raf.getFilePointer());
/*
* void writeInt(int d)
* 将给定的int值的4个字节一次性写入文件,等同
* 上面的4次write操作
*/
raf.writeInt(max);
System.out.println("pos:"+raf.getFilePointer());
/*
* RAF提供了所有基本类型的写出操作
*/
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.seek(0);
System.out.println("pos:"+raf.getFilePointer());
/*
* raf也提供了读取基本类型的相关方法
*/
int d = raf.readInt();
System.out.println(d);//max
System.out.println("pos:"+raf.getFilePointer());
//读取long
//1将指针移动到long的第一个字节位置
raf.seek(8);
//2连续读取8个字节
long l = raf.readLong();
System.out.println(l);
double dou = raf.readDouble();
System.out.println(dou);
//指针应当再次到达文件末尾
System.out.println("pos:"+raf.getFilePointer());
/*
* 当调用readInt这样的方法过程中发现读取到了文件
* 末尾时,会抛出EOFException表示文件末尾。
* EOF end of file
*/
// d = raf.readInt();
// System.out.println(d);
raf.close();
}
}
6.读取字符串
package raf;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
public class ReadStringDemo {
public static void main(String[] args) throws IOException {
/*
* 将note.txt文件中的所有字符读取出来
*/
RandomAccessFile raf
= new RandomAccessFile("note.txt", "r");
/*
* 若想读取一个字符,应当读取几个字节?
* 不同的字符集,对应的文字占用的字节量是不同的
* 英文是相同的,无论哪个字符集都是1字节,都用
* 的asc编码的部分。但是对于中文而言则不然,
* 在GBK编码中,每个中文字占用2字节,在utf-8中
* 每个中文字占用3个字节。
* 占用的这些字节对应的2进制不全是表达字符本身的
* 数据,还含有算法(通过这个,得知应当读取几个
* 字节表示一个文字)。
*/
/*
* 创建一个与文件一样大的字节数组(若文件过大,
* 不适合这样做)
*/
byte[] data = new byte[(int)raf.length()];
//读取指定的字节量(这里等于将文件所有字节读入)
raf.read(data);
/*
* String的构造方法允许我们将指定的字节数组中
* 所有的字节按照给定的字符集转换为一个字符串
*/
String string = new String(data,"UTF-8");
System.out.println(string);
raf.close();
}
}
7.向文件中写出字符串
package raf;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
public class WriteStringDemo {
public static void main(String[] args) throws IOException {
RandomAccessFile raf
= new RandomAccessFile("raf.txt", "rw");
String line = "像一颗海草海草海草海草~";
/*
* 将字符串首先根据给定的字符集转换为一组字节
* 常见的支持中文的字符集有:
* GBK,UTF-8
*/
byte[] data = line.getBytes("UTF-8");
raf.write(data);
raf.write("随风飘摇~".getBytes("UTF-8"));
System.out.println("写出完毕!");
raf.close();
}
}