Java ,IO流,文件的分割與合併

package fileSplitAndBination;

import java.io.BufferedOutputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.RandomAccessFile;
/**
 * 文件的分割
 * @author 風瀟瀟
 *
 */
public class FileSplit {
	//文件路徑
	private String srcPath;
	//文件對象
	private File src;
	//源文件大小
	private long fileSize;
	//源文件名
	private String name;
	//分割塊數
	private int blocks;
	//每塊大小
	private long blockSize;
	//分割後存儲路徑

	public FileSplit(String srcPath){
		this(srcPath,10);//默認分割爲十塊
	}
	/**
	 * 默認爲讀取源文件目錄,和分割塊數
	 * @param srcPath
	 * @param blocks
	 */
	public FileSplit(String srcPath,int blocks){
		this.srcPath = srcPath;
		this.blocks=blocks;
		initial();
	}
	/**
	 * 讀取文件名,文件大小,計算分割後每塊大小
	 */
	public void initial(){
		this.src=new File(srcPath);
		if(!src.isFile()){
			System.out.println("傳入文件夾只能分割文件,或文件不存在");
			return;
		}
		this.fileSize=src.length();//文件大小
		this.name=src.getName();//文件名
		this.blockSize = fileSize/blocks;//分割塊大小
	}
	/**
	 * 指定輸出目錄
	 * @param destPath
	 * @throws IOException
	 */
	public void split(String destPath) throws IOException{
		File dest = new File(destPath);
		if(dest.isFile()||dest.isDirectory()){
			System.out.println("無法存儲到已有文件或文件夾中中,請指定未建立的文件夾路勁");//爲方便合併,限定必須爲未建立的文件夾路徑
			return;
		}
		if(!dest.exists()){
			dest.mkdirs();
		}
		long head=0;
		long size=this.blockSize;
		for(int i=0;i<blocks;i++){
			if(i==blocks-1){
				size=this.fileSize-head;
			}
			splitDtails(i,dest,head,size);
			head+=size;
		}
		/**
		 * 輸出分割信息
		 * 由於分割信息名制定
		 * 所以限定未建立的文件夾
		 * 以便合併時讀取
		 */
		File info = new File(dest,"splitInfo");
		DataOutputStream dos = new DataOutputStream(
							   new BufferedOutputStream(
						       new FileOutputStream(info)));
		dos.writeUTF(this.name);
		dos.writeInt(this.blocks);
		dos.flush();
		dos.close();		
	}
			
	
	private void splitDtails(int idx,File dest,long head,long size) throws IOException{
		File destSplit = new File(dest,this.name+"第"+idx+"部分");
		if(destSplit.exists()){
			destSplit.delete();
		}//避免重複寫入
		RandomAccessFile is = new RandomAccessFile(src,"r");
		OutputStream os = new BufferedOutputStream(new FileOutputStream(destSplit,true));
		is.seek(head);
		byte[] flush =new byte[1024];
		int len=0;
		long sum=0;
		//此處要尤爲注意,應按實際size寫入,最後一次
		//同文件複製不同,此處無法通過返回-1來推出循環
		//因爲文件分割所以在size邊界外還是有字節存在
		//若直接使用len,就無法正確讀取!
		while(-1!=(len=is.read(flush))){
			if(size-len>=0){
				os.write(flush, 0, len);
				size-=len;
			}else{
				os.write(flush,0,(int)size);
				break;
			}
		}
		os.flush();
		os.close();
		is.close();
	}
	/**、
	 * 通過制定大小來分割文件
	 * @param destPath
	 * @param blockSize
	 * @throws IOException
	 */
	public void splitBySize(String destPath,long blockSize) throws IOException{
		if(blockSize>fileSize){
			blockSize = fileSize;
		}
		this.blockSize=blockSize;
		this.blocks = (int)(Math.ceil((fileSize*1.0/blockSize)));
		split(destPath);
	}
	public static void main(String[] args) {
		FileSplit fs = new FileSplit("G:/《Java核心技術 卷1 基礎知識(原書第9版)》(完整中文版).pdf");
		try {
			fs.split("G:/test");
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}

文件的合併
package fileSplitAndBination;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

public class FileBination {
	private String srcPath;
	private String destPath;
	private String fileName;
	private int blocks;
	public FileBination(String srcPath, String destPath) throws IOException {
		this.srcPath = srcPath;
		this.destPath = destPath;
		binationIntial();
	}
	public void binationIntial() throws IOException{
		File src = new File(srcPath);
		File splitInfo = new File(src,"splitInfo");
		if(!src.isDirectory()){
			System.out.println("請提供分割文件絕對路徑!");
			return;
		}else if(!splitInfo.exists()||!splitInfo.isFile()){
			System.out.println("分割信息文件不存在或損壞");
			return;
		}else{
			DataInputStream dis = new DataInputStream(
							      new BufferedInputStream(
							      new FileInputStream(splitInfo)));
			this.fileName=dis.readUTF();
			this.blocks = dis.readInt();
		}
	}
	public void bination() throws IOException{
		File bFile = new File(destPath, fileName);
		for(int i=0 ;i<blocks;i++){
			if(!binationDtail(bFile,i)){
				bFile.delete();
				break;
			}
		}
	}

	private boolean binationDtail(File bFile,int i) throws IOException{
		File inFile = new File(srcPath,fileName+"第"+i+"部分");
		OutputStream os = new BufferedOutputStream(new FileOutputStream(bFile,true));
		InputStream is=null;
		boolean ok=true;
		if(!inFile.exists()){
			System.out.println("第"+i+"個分割文件損壞");
			ok=false;
		}else{
			is = new BufferedInputStream(new FileInputStream(inFile));
			int len =0;
			byte[] flush = new byte[1024];
			while(-1!=(len=is.read(flush))){
				os.write(flush, 0, len);
			}
		}
		os.flush();
		os.close();
		is.close();
		return ok;
	}
	public static void main(String[] args) {
		try {
			FileBination fb =new FileBination("G:/test","D:/");
			fb.bination();
		} catch (IOException e) {
			e.printStackTrace();
		}
		
	}

}




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章