[IO]——文件的分割與合併

public class SplitFile {
	//文件的路徑
	private String filePath;
	//文件名
	private String fileName;
	//文件大小
	private long length;
	//塊數
	private int size;
	//每塊的大小
	private long blockSize;
	//分割後的存放目錄
	private String destBlockPath;
	//每塊的名稱
	private List<String> blockPath;
	
	public SplitFile(){
		blockPath = new ArrayList<String>();
	}
	public SplitFile(String filePath,String destBlockPath){
		this(filePath,destBlockPath,1024);		
	}
	public SplitFile(String filePath,String destBlockPath,long blockSize){
		this();
		this.filePath= filePath;
		this.destBlockPath =destBlockPath;
		this.blockSize=blockSize;
		init();
	}
	
	/**
	 * 初始化操作 計算 塊數、確定文件名
	 */
	public void init(){
		File src =null;
		//健壯性
		if(null==filePath ||!(((src=new File(filePath)).exists()))){
			return;
		}
		if(src.isDirectory()){
			return ;
		}
		//文件名
		this.fileName =src.getName();
		
		//計算塊數 實際大小 與每塊大小
		this.length = src.length();
		//修正 每塊大小
		if(this.blockSize>length){//輸入錯誤時修正!!!
			this.blockSize =length;
		}
		//確定塊數		
		size= (int)(Math.ceil(length*1.0/this.blockSize));
		//確定文件的路徑
		initPathName();
	}
	
	private void initPathName(){
		for(int i=0;i<size;i++){
			this.blockPath.add(destBlockPath+"/"+this.fileName+i+".txt");
		}
	}
	
	/**
	 * 文件的分割
	 * 0)、第幾塊
	 * 1、起始位置
	 * 2、實際大小
	 * @param destPath 分割文件存放目錄
	 * @throws IOException 
	 */
	public void split() throws IOException{	
		long beginPos =0; //起始點
		long actualBlockSize =blockSize; //實際大小		
		//計算所有塊的大小、位置、索引
		for(int i=0;i<size;i++){
			if(i==size-1){ //最後一塊
				actualBlockSize =this.length-beginPos;
			}			
			spiltDetail(i,beginPos,actualBlockSize);
			beginPos+=actualBlockSize; //本次的終點,下一次的起點
		}
	}
	/**
	 * 文件的分割 輸入 輸出
	 * 文件拷貝
	 * @param idx 第幾塊
	 * @param beginPos 起始點
	 * @param actualBlockSize 實際大小
	 * @throws IOException 
	 */
	private void spiltDetail(int idx,long beginPos,long actualBlockSize) throws IOException{
		//1、創建源
		File src = new File(this.filePath);  //源文件
		File dest = new File(this.blockPath.get(idx)); //目標文件
		//2、選擇流
		java.io.RandomAccessFile raf = null;  //輸入流
		BufferedOutputStream bos=null; //輸出流
		try {
			raf=new java.io.RandomAccessFile(src,"r");
			bos =new BufferedOutputStream(new FileOutputStream(dest));
			
			//讀取文件
			raf.seek(beginPos);
			//緩衝區
			byte[] flush = new byte[1024];
			//接收長度
			int len =0;
			while(-1!=(len=raf.read(flush))){				
				if(actualBlockSize-len>=0){ //查看是否足夠
					//寫出
					bos.write(flush, 0, len);
					actualBlockSize-=len; //剩餘量
				}else{ //寫出最後一次的剩餘量
					bos.write(flush, 0, (int)actualBlockSize);
					break;
				}
			}
			
			
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}finally{
			bos.close();
			raf.close();
		}
		
	}
	/**
	 * 文件的合併
	 * @throws IOException 
	 */
	public void merge(String destPath) throws IOException{
		//創建源
		File dest =new File(destPath);
		//選擇流
		BufferedOutputStream bos=null; //輸出流
		try {
			bos =new BufferedOutputStream(new FileOutputStream(dest,true)); //追加
			BufferedInputStream bis = null;
			for (int i = 0; i < this.blockPath.size(); i++) {
				bis = new BufferedInputStream(new FileInputStream(new File(this.blockPath.get(i))));
				//緩衝區
				byte[] flush = new byte[1024];
				//接收長度
				int len =0;
				while(-1!=(len=bis.read(flush))){						
					bos.write(flush, 0, len);
				}
				bos.flush();
				bis.close();
			}
		} catch (Exception e) {
		}finally{
			bos.close();
		}		
	}

	public static void main(String[] args) throws IOException {
		SplitFile split = new SplitFile("E:/others/good.txt","E:/others/",1);
		System.out.println(split.size);
		split.split();
		split.merge("E:/others/1234.txt");
	}
}

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