读书人

java中多线程操作资料的复制及剪切

发布时间: 2012-12-18 12:43:41 作者: rapoo

java中多线程操作文件的复制及剪切

?

对文件的剪切可以使用File的public boolean renameTo(File dest)方法,重命名此抽象路径名表示的文件。相当于剪切并且重命名。但是此方法是与平台相关的,重命名操作无法将一个文件从一个文件系统移动到另外一个文件系统。这是导致文件操作失败的原因之一,还有的一个可能原因是:目标路径已经存在此文件。

public boolean move(){boolean flag = false;      File oldFile = new File("D:\\123.txt");String newName = "D:\\123 - 副本.txt";File newFile = new File(newName);flag = oldFile.renameTo(newFile);return flag;}

?如果oldFile和newFile存在于不同的文件系统,则flag会返回false

?如果newFIle已经存在,则flag会返回false


在需要跨平台且文件比较大的时候,采用多线程进行文件传输是不错的选择。以下为具体方法:

根据文件大小(x字节),启动n个线程(n=x/β,β为常量),每个线程i以共享方式打开文件,从第i*β个字节处开始读取。

写入文件同理,先创建x大小的文件,然后每个线程往第i*β个字节处写入。

n的数量不能太多,常量β的值很重要,是可以配置的,一般设置为20m。

public class FileThread implements Runnable{private String oldPath = null;private String newPath = null;private int startIndex = 0;private int len = 0;private int count = 0;public FileThread(String oldPath , String newPath , int startIndex , int len , int count){this.oldPath = oldPath;this.newPath = newPath;this.startIndex = startIndex;this.len = len;this.count = count;}public void run() {CopyFileTest cf = new CopyFileTest(); int tmpCount = cf.readFile(oldPath, newPath, startIndex, len); if( count == tmpCount)cf.deleteFile(oldPath);}}

?

import java.io.File;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.IOException;import java.io.RandomAccessFile;public class CopyFileTest {//β=20mb参数,为常量,单位为kbpublic static int β = 20 * 1024 * 1024;public static int count = 0;public void deleteFile(String filePath){File file = new File(filePath);file.delete();}//新建一个文件,大小为size 单位是kbpublic void createFile(String filePath , int size){FileOutputStream fs;try {fs = new FileOutputStream(filePath);//for (int i = 0; i < n + 1; i++) {byte[] buffer = new byte[ size ]; //创建size大小的文件fs.write(buffer);//}try {fs.close();} catch (IOException e) {System.out.println("创建文件失败");e.printStackTrace();}} catch (Exception e) {e.printStackTrace();}File file = new File(filePath);System.out.println("size:" + file.length());}public int readFile(String oldPath , String newPath , int startIndex , int len){int byteLen = 0;File oldFile = new File(oldPath);FileInputStream fin = null;//FileOutputStream fos = null;RandomAccessFile fos = null;try {fin = new FileInputStream(oldFile);//参数rw表示以读写方式打开文件fos = new RandomAccessFile(newPath , "rw");byte[] buff = new byte[ 20 * 1024 * 1024];fin.skip(startIndex);fos.seek(startIndex);int currentSumLen = 0;while( ((byteLen = fin.read(buff)) > 0 ) && currentSumLen < len){//从第startIndex个字段开始,直到endIndexfos.write(buff , 0 , len);currentSumLen += byteLen;}System.out.println("byteLen:" + byteLen);fos.close();fin.close();} catch (Exception e) {System.out.println("复制文件出错!" + len + "--" + byteLen);e.printStackTrace();}count ++;System.out.println("片段结束复制:" + startIndex + "---" + len);return count;}public void copyFile(String oldPath , String newPath ){File oldFile = new File(oldPath);//创建线程个数,至少创建一个线程写入文件int n = 1;if( oldFile.exists() ){int fileSize = (int) oldFile.length(); //单位为kbSystem.out.println("size:" + fileSize);System.out.println("β * n:" + β * n);//在目标路径下创建新文件this.createFile(newPath, fileSize);n = (fileSize - 1) / β + 1;   //启动n个线程System.out.println("n:"+n);FileThread fthread = null;int tmp = 0;for( int i = 0 ; i < n ; i++){if( i == (n -1) )tmp = fileSize - i * β;elsetmp = β;//从i*β处开始写入,写tmp字节fthread = new FileThread( oldPath , newPath , i * β , tmp , n);//启动线程new Thread(fthread).start();}}else{System.out.println(oldPath + "不存在!");}}public boolean move(){boolean flag = false;File oldFile = new File("D:\\123.txt");String newName = "D:\\123 - 副本.txt";File newFile = new File(newName);flag = oldFile.renameTo(newFile);return flag;}public static void main(String args[]){CopyFileTest cf = new CopyFileTest();//System.out.println(cf.move());cf.copyFile("E:\\test\\ready.rar", "F:\\share\\ready.rar" );  //测试}}
?

?

?

?

?

?

读书人网 >编程

热点推荐