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参数,为常量,单位为kb
	public static int β = 20 * 1024 * 1024;
	public static int count = 0;
	
	
	public void deleteFile(String filePath){
		File file = new File(filePath);
		file.delete();
	}
	
//	新建一个文件,大小为size 单位是kb
	public 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个字段开始,直到endIndex
				fos.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(); //单位为kb
			System.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 * β;
				else
					tmp = β;
//				从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" );  //测试
	}

}
 

 

 

 

 

 

你可能感兴趣的:(java,thread,多线程,F#)