随机流(RandomAccessFile):它不是一种流,是Object的直接子类,所以也不属于Io流。它融合了InputStream和OutputStream的功能,即能读又能写。 详细介绍
随机访问:通过ceek()方法,可以随机在任意位置读写文件。
对象申明:
RandomAccessFile raf = newRandomAccessFile(File file, String mode);
参数说明:
file:文件路径和目录路径名的抽象表示。
mode:可读性;可选 "r":可读,"w" :可写,"rw":可读写,"rws":读写,同步,"rwd":读写,不对metadata同步更新。详细介绍
File file1 = new File(file,"Access.txt");
Boolean b = file1.exists()?file1.delete():file1.createNewFile();
RandomAccessFile raf = new RandomAccessFile(file1, "rw"); //rw 权限为读写
读写操作:
// 创建一个File 实例
File file = new File("C:\\Users\\Mr.wang\\Desktop\\单词\\AccessTest");
/*判断是否有这个目录是否存在 ,不存在则创建 */
if(!file.exists()) {
file.mkdirs();
}
File file1 = new File(file,"Access.txt");
Boolean b = file1.exists()?file1.delete():file1.createNewFile();
RandomAccessFile raf = new RandomAccessFile(file1, "rw"); //rw 权限为读写
/*写入单词*/
byte c = 'C';
raf.write(c);//只写入一个字节
int i = 0X7fffffff;//32字节 需要写四次
raf.write(i>>>24&0xff);
raf.write(i>>>16&0xff);
raf.write(i>>>8&0xff);
raf.write(i);
/*等效于上面的代码,封装的*/
raf.writeInt(i);
/*写入汉字*/
byte[] chinese = "中".getBytes();
raf.write(chinese);
System.out.println(raf.getFilePointer());
/*读取字节*/
raf.getFilePointer();
raf.seek(0); //读文件必须把指针移到头部
byte[] bytess = new byte[(int)raf.length()];
System.out.println("数值:" +raf.read(bytess));
System.out.println(Arrays.toString(bytess));
String s = new String(bytess,"gbk");
System.out.println(s);
raf.close();
Read():读。
Write():写。
getPointer():获得当前指针位置。
ceek():设置指针位置。
多线程与单线程copy:
package test;
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.Date;
import java.util.concurrent.CountDownLatch;
/**
* 多线程copy文件
* @author Mr.wang
*
*/
public class RanddomAccessFileDeMO {
public static void main(String[] args) throws IOException {
/*创建文件*/
File file = new File("C:\\Users\\Mr.wang\\Desktop\\单词\\AccessTest","千影.zip");
File file3 = new File("C:\\Users\\Mr.wang\\Desktop\\单词\\AccessTest","Access.txt");
Boolean a = file.exists()?file.delete():file.createNewFile();
File file1 = new File("C:\\Users\\Mr.wang\\Desktop\\千应.zip");
if(!file1.exists()) {
System.out.println("文件不存在");
return;
}else {
System.out.println("文件存在");
}
long date = new Date().getTime();
RandomAccessFile rdfR = new RandomAccessFile(file1,"r"); //读文件
RandomAccessFile rdfW = new RandomAccessFile(file,"rw"); //写文件
Long Rfilesizi = rdfR.length();
rdfW.setLength(Rfilesizi);//设置文件大小
/*
* 单线程写入
*
int len =0;
while((len=rdfR.read(bytes))!=-1) {
rdfW.write(bytes, 0, bytes.length);
}
*/
/*多线程写入*/
final int num = 1000000; //割块文件每块大小
int filesizi = (int) (Rfilesizi/num);//线程数量
final CountDownLatch latch = new CountDownLatch(filesizi);
for(int i=0; i<filesizi; i++) {
int ac = i*num;//开始下标
int ca = i;
new Thread(new Runnable() {
@Override
public void run() {
try {
byte[] bytes = new byte[1024];
rdfW.seek(ac);
rdfR.seek(ac);
int len = 0; //写入的字节数
for(int max = 0 ;(len=rdfR.read(bytes))!=-1&& max < num;max++) {
rdfW.write(bytes, 0, len);
max++;
}
latch.countDown();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}).start();
//System.out.println(i);
}
try {
latch.await();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
rdfR.close();
rdfW.close();
long date1 = new Date().getTime();
System.out.println((date1-date)+ "毫秒");
}
}
大文件进行多线程有优势,但有线程资源消耗。
小文件单线程优势。