RandomAccessFile的简介
我们平常创建流对象关联文件,开始读文件或者写文件都是从头开始的,不能从中间开始,如果是开多线程下载一个文件我们之前学过的FileWriter或者FileReader等等都无法完成,而当前介绍的RandomAccessFile他就可以解决这个问题,因为它可以指定位置读,指定位置写的一个类,通常开发过程中,多用于多线程下载一个大文件
常用方法简介
构造方法:RandomAccessFile raf = newRandomAccessFile(File file, String mode);
其中参数 mode 的值可选 “r”:可读,“w” :可写,“rw”:可读性;
成员方法:
? seek(int index);可以将指针移动到某个位置开始读写;
? setLength(long len);给写入文件预留空间:
示例
public class DownLoadThread extends Thread {
?private long start;private File src;private long total;private File desc;
?/*** * @param start* 开始下载的位置* @param src* 要下载的文件* @param desc* 要下载的目的地* @param total* 要下载的总量*/public DownLoadThread(long start, File src, File desc, long total) {this.start = start;this.src = src;this.desc = desc;this.total = total;}
?@Overridepublic void run() {try {// 创建输入流关联源,因为要指定位置读和写,所以我们需要用随机访问流RandomAccessFile src = new RandomAccessFile(this.src, "rw");RandomAccessFile desc = new RandomAccessFile(this.desc, "rw");
?// 源和目的都要从start开始src.seek(start);desc.seek(start);// 开始读写byte[] arr = new byte[1024];int len;long count = 0;while ((len = src.read(arr)) != -1) {//分三种情况if (len + count > total) {//1.当读取的时候操作自己该线程的下载总量的时候,需要改变lenlen = (int) (total - count);desc.write(arr, 0, len);//证明该线程下载任务已经完毕,结束读写操作break;} else if (len + count < total) {//2.证明还没有到下载总量,直接将内容写入desc.write(arr, 0, len);//并且使计数器任务累加count += arr.length;} else {//3.证明改好到下载总量desc.write(arr, 0, len);//结束读写break;}}src.close();desc.close();
?} catch (Exception e) {e.printStackTrace();}}
}
public class TestRandomAccess {public static void main(String[] args) {//关联源File src = new File("a.txt");//关联目的File desc = new File("b.txt");//获取源的总大小long length = src.length();// 开两条线程,并分配下载任务new DownLoadThread(0, src, desc, length / 2).start();new DownLoadThread(length / 2 , src, desc, length - (length / 2)).start();}
}
参考
RandomAccessFile的常见用法