RandomAccess
RandomAccessFile类支持“随机访问”方式,这里“随机”是指可以跳转到文件的任意位置处读写数据。在访问一个文件的时候,不必把文件从头读到尾,而是希望像访问一个数据库一样“随心所欲”地访问一个文件的某个部分,这时使用RandomAccessFile类就是最佳选择。
RandomAccessFile对象类有个位置指示器,指向当前读写处的位置,当前读写n个字节后,文件指示器将指向这n个字节后面的下一个字节处。刚打开文件时,文件指示器指向文件的开头处,可以移动文件指示器到新的位置,随后的读写操作将从新的位置开始。
构造方法:RandomAccessFile(File file , String mode)
文件参数mode:
r | 以只读的方式打开,调用该对象的任何write(写)方法都会导致IOException异常 |
---|---|
rw | 支持文件的读取或写入。若文件不存在,则创建 |
rws | 以读、写方式打开,与“rw”不同的是,还要对文件内容的每次更新都同步更新到潜在的存储设备中去。这里的“s”表示synchronous(同步)的意思 |
rwd | 打开以便读取和写入,对于 “rw”,还要求对文件内容的每个更新都同步写入到底层存储设备。 |
方法:
seek() 定位到指定位置
绝对的量
skip()
相对的量
用法:
package com.yongjun.io;
import java.io.FileOutputStream;
import java.io.RandomAccessFile;
import org.junit.Test;
/**
* 随机访问文件
* @author Frenzy Fan
*
*/
public class RandomAccessFileDemo {
public static void main(String[]args) throws Exception {
RandomAccessFile raf=new RandomAccessFile("e:/xx.txt","rwd");
raf.write("helloworld".getBytes());
//定位文件
raf.seek(3);
int c=-1;
while((c=raf.read())!=-1) {
System.out.print((char)c);
}
raf.close();
}
/**
* 文件内容重复
* @throws Exception
*/
@Test
public void duplicateFile() throws Exception {
RandomAccessFile raf=new RandomAccessFile("e:/xx.txt","rw");
FileOutputStream fos=new FileOutputStream("e:/yy.txt");
byte[]buffer=new byte[1024];
int len=-1;
while((len=raf.read(buffer))!=-1) {
fos.write(buffer,0,len);
}
raf.seek(0);
while((len=raf.read(buffer))!=-1) {
fos.write(buffer,0,len);
}
raf.seek(0);
while((len=raf.read(buffer))!=-1) {
fos.write(buffer,0,len);
}
fos.close();
raf.close();
}
}
利用RandomAccessFile进行多线程复制
package com.yongjun.io;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
public class MulThreadCopyFile {
static int i=0;
static int block=0;
public static void main(String []args) throws Exception {
//源文件
File srcFile=new File("d:/hello.txt");
RandomAccessFile srcRaf=new RandomAccessFile(srcFile,"r");
//文件长度
int srcLength=(int)srcFile.length();
//目标文件
File destFile=new File("e:/halo.txt");
final RandomAccessFile destRaf=new RandomAccessFile(destFile,"rw");
destRaf.setLength(srcLength);
//使用的线程数
int count=3;
//计算每个线程复制文件块大小
block=srcLength/count;
//开启count个线程
for( i=0;i<count;i++) {
//匿名内部类
Thread t =new Thread() {
public void run() {
int temp=i;
int start=temp*block;
int end=0;
//是否是最后一个线程
if(temp!=(count-1)) {
end=(temp+1)*block-1;
}
else {
end=srcLength-1;
}
//定位文件指针
try {
srcRaf.seek(start);
destRaf.seek(start);
//
int bufSize =end-start+1;//判断每次读多少
byte[]buf=new byte[bufSize];//每次读的大小
srcRaf.read(buf);//读满
destRaf.write(buf);//写入到目标文件
System.out.println(temp+"over");
} catch (Exception e) {
e.printStackTrace();
}//下一次读的位置
}
};
t.start();
t.join();
}
Thread.sleep(10000);
System.out.println("over");
}
}