黑马程序员技术交流社区
标题:
用java进行复制文件(考虑使用多线程),能系统自带快吗??
[打印本页]
作者:
lingyuezhixing
时间:
2015-11-28 20:36
标题:
用java进行复制文件(考虑使用多线程),能系统自带快吗??
我用了四条输入线程,加四条输出线程,来拷贝源文件,
结果还是慢了电脑自带的慢一大截。
希望大神能给个超电脑的。。
下面是我用多线程重新做的大文件拷贝程序:
import java.io.IOException;
/*
* 将一个电影文件,拷贝到其他盘。模拟下载,要求使用多线程
* 分析:
* 1,通过File对象关联源文件,并获取其大小。
* 2,通过File对象创建一个和源文件大小相同的(空)文件
* 3,通过随机流RandomAccessFile读取源文件,
* 4,将读取的数据写入到输出管道流PipedOutputStream,
* 5,管道读取流PipedInputStream读取输出流中的数据,并通过随机流写入到目的文件中。
*
*/
public class TestTwo {
public static void main(String[] args) throws IOException {
Copy.copy("C:\\Mon.mp4","C:\\Moncy.mp4");
}
}
复制代码
Copy进行拷贝操作:
import java.io.File;
import java.io.IOException;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;
import java.io.RandomAccessFile;
public class Copy {
public static void main(String[] args) {
}
public static boolean copy(String source, String destination) throws IOException {
File socefile = new File(source);
File destfile = new File(destination);
if(socefile.isHidden())
throw new RuntimeException("源文件不可操作");
//目的文件初始化,使其和源文件大小一致。
RandomAccessFile soceRaf = new RandomAccessFile(socefile,"r");
RandomAccessFile destRaf = new RandomAccessFile(destfile,"rwd");
destRaf.setLength(soceRaf.length());
long index = soceRaf.getFilePointer();
soceRaf.close();
destRaf.close();
//把源文件切成4段,每段的最小的(最接近负无穷大)double 值,该值大于等于参数,
//保证数据不丢失。最后一段单独处理,因为数据可能会小于len。
long len = (long) Math.ceil(socefile.length()/4);
for(int x=0 ; x<4 ; x++){
PipedOutputStream pos = new PipedOutputStream();
PipedInputStream pis = new PipedInputStream(pos);
//为了使每个线程都有一个自己独立的指针,为每个对象建立独自的随机流
new Thread(new PipedOut
(pos,new RandomAccessFile(socefile,"r"),index,len)).start();;
new Thread(new PipedIn
(pis,new RandomAccessFile(destfile,"rwd"),index,len)).start();
index = index + len ;
}
return true;
/*无限代码,用于测试的
* PipedOutputStream pos = new PipedOutputStream();
PipedInputStream pis = new PipedInputStream(pos);
long len = soceRaf.length();
new Thread(new PipedOut(pos,soceRaf,index,len)).start();
new Thread(new PipedIn(pis,destRaf,index,len)).start();
*/
}
}
复制代码
PipedOut :通过随机流读取,并写入到管道流中:
import java.io.BufferedOutputStream;
import java.io.IOException;
import java.io.PipedOutputStream;
import java.io.RandomAccessFile;
public class PipedOut implements Runnable{
BufferedOutputStream pos;
RandomAccessFile soceRaf;
long index;
long len;
PipedOut(PipedOutputStream pos, RandomAccessFile soceRaf, long index, long len) {
super();
this.pos = new BufferedOutputStream(pos);
this.soceRaf = soceRaf;
this.index = index;
this.len = len;
}
public void run() {
try {
byte[] buf = new byte[1024*1024*20];
int length = 0 ;
soceRaf.seek(index);//设置指针位置
//如果没有循环超出数据位置,或者在到结尾。
while(soceRaf.getFilePointer()<index+len){
if((length=soceRaf.read(buf))!=-1){
pos.write(buf,0,length);
pos.flush();
}
else
break;
}
//如果是因为循环超出数据位置导致的结束,则计算出有效的数组长度
if(length==buf.length){
length =(int) ((long)length - ( soceRaf.getFilePointer()-(index+len) ));
System.out.println(length);
pos.write(buf,0,length);
}
pos.close();
soceRaf.close();
}
catch (IOException e) {
e.printStackTrace();
}
/*
* 无效代码用于测试的
try {
byte[] buf = new byte[1024*100];
int length = 0 ;
soceRaf.seek(index);//设置指针位置
//如果没有循环超出数据位置,或者在到结尾。
while((length=soceRaf.read(buf))!=-1){
pos.write(buf,0,length);
pos.flush();
}
pos.close();
soceRaf.close();
}
catch (IOException e) {
e.printStackTrace();
}
*/
}
}
复制代码
PipedIn 从管道流中读取数据,并通过任意流写入到目的文件中:
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.PipedInputStream;
import java.io.RandomAccessFile;
public class PipedIn implements Runnable {
BufferedInputStream pis;
RandomAccessFile destRaf;
long index;
long len;
PipedIn(PipedInputStream pis, RandomAccessFile destRaf, long index, long len) {
super();
this.pis =new BufferedInputStream(pis);
this.destRaf = destRaf;
this.index = index;
this.len = len;
}
public void run() {
try {
byte[] buf = new byte[1024*1024*20];
int length = 0 ;
destRaf.seek(index);//设置指针位置
//读取管道流中的数据,并写入目的文件中
while((length=pis.read(buf))!=-1){
destRaf.write(buf,0,length);
}
pis.close();
destRaf.close();
System.out.println("over");
} catch (IOException e) {
e.printStackTrace();
}
}
}
复制代码
比起单线程切实是快乐好多倍,但是和电脑自带的比起来,简直就是满满的挫败感。。。
感觉自己当初的懵懂的大志疑惑幻想,是怎么的可笑,如果还有比windows更快更好的,windows一定早就用了吧?
换句话说,windows现在用的岂能不是最好最优的,,,
呵,我也只能带着自己无知无畏最后的无奈匆匆一笑,希望在今后遇到问题能去进一步想想,少一些不切实际幻想,
有想法是好的,关键跟要有这样的实力,敢于幻想,更要能加以辩论!
作者:
Weidan
时间:
2015-11-29 22:21
题外话:我拷贝大文件的时候习惯用fastcopy 可以自定义复制的内存 确实要比windows自带的快得多 windows自带的给的内存才128M
作者:
lingyuezhixing
时间:
2015-11-30 00:07
Weidan 发表于 2015-11-29 22:21
题外话:我拷贝大文件的时候习惯用fastcopy 可以自定义复制的内存 确实要比windows自带的快得多 windows自带 ...
谢谢!但是我用的是固态硬盘,不差这点时间
介绍给室友了
作者:
wei_john
时间:
2015-12-9 11:48
参考下别人的高级算法吧。我们的是最基本的算法而已
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2