1. 程式人生 > >IO練習--拆分合並檔案

IO練習--拆分合並檔案

需求:

將一個檔案拆分成幾個碎片檔案,在將這幾個碎片檔案合成原檔案。


主要問題:

1.合併檔案的時候怎麼知道原檔案變成幾塊了?怎麼知道原檔案的名稱和型別?

其實只要在拆分檔案的時候,儲存一個配置檔案資訊到硬碟上面,將檔案變成幾塊和檔案的名稱記錄在上面就好了,合併檔案的時候在把這個檔案讀取出來,拿出其中的資訊。


首先是拆分:

public static void main(String[] args) throws IOException {
		// TODO Auto-generated method stub
		File file=new File("c:\\專案檔案\\截圖.bmp");
		SplitFile(file);
	}
       //傳入要切割的檔案
	private static void SplitFile(File file) throws IOException {
		Properties pro=new Properties();//建立properties用來儲存鍵值對
		//用讀取流關聯原始檔
		FileInputStream  fis=new FileInputStream(file);
		//建立緩衝區,指定每一塊檔案的大小
		byte[] buf=new byte[1024*1024];
		//建立輸出流
		FileOutputStream fo=null;
		//指定要放到的資料夾
		File dir=new File("c:\\part");
		//健壯性判斷,如果不存在,建立多級目錄
		if(!dir.exists()){
			dir.mkdirs();
		}
		
		int len=0;
		//計數器,用來記錄碎塊數
		int count=1;
		
		while((len=fis.read(buf))!=-1){
			fo=new FileOutputStream(new File(dir,(count++)+".part"));//例項化輸出流,並將目的檔案傳給建構函式,每個塊名稱不同
			fo.write(buf,0,len);//寫入
			fo.close();//每次寫入完畢,關閉流
		}
		fo=new FileOutputStream(new File(dir, "my.properties"));//輸出流,將目的檔案傳給它
		
		//將被切割檔案的資訊儲存到pro集合中。
		pro.setProperty("count", count+"");
		pro.setProperty("name", file.getName());
		//使用store方法儲存到硬碟中
		pro.store(fo, "pei zhi info");
		
		
		fis.close();
		fo.close();
	}

執行:

圖片被分成5快,並且配置資訊裡面存入了count和name。


然後是合併:

public static void main(String[] args) throws IOException {
		// TODO Auto-generated method stub
		//MergeDemo(null);
		File file=new File("c:\\part");
		MergeDemo2(file);
	}

	private static void MergeDemo2(File dir) throws IOException {
		//取出配置檔案資訊,通過過濾器將properties檔案取出,過濾器自己寫一下即可==========
		File[] files=dir.listFiles(new SuffixFilter(".properties"));
		//如果不是一個配置檔案,丟擲異常。
		if(files.length!=1){
			throw new RuntimeException(dir+"該目錄下的propertises不合規");
		}
		//取出
		File confile=files[0];
		
		
		//獲取檔案中的資訊==========
		FileInputStream fi=new FileInputStream(confile);
		
		Properties properties=new Properties();
		//load方法,將讀取流中的資訊存入properties
		properties.load(fi);
		//取出配置檔案中切割檔案的個數和原始檔的名稱
		int count=Integer.parseInt(properties.getProperty("count"));
		String filename=properties.getProperty("name");
		
		
		
		//做一個健壯性判斷,取出目錄中所有的碎片檔案,若客戶少下載了檔案,則要提醒
		File[] partFiles=dir.listFiles(new SuffixFilter(".part"));
		
		if(partFiles.length!=count-1){
			throw new RuntimeException("檔案丟失");
		}
		
		
		//合併所有的碎片檔案,將它和流物件關聯並存儲到集合當中==========
		ArrayList<FileInputStream> a1=new ArrayList<FileInputStream>();
		
		for(int x=1;x<=count-1;x++){
			a1.add(new FileInputStream(new File(dir,x+".part")));
		}
		//拿到列舉,傳給序列流
		Enumeration<FileInputStream> enumeration=Collections.enumeration(a1);
		//建立序列流,將多個流合併為一個序列流
		
		SequenceInputStream sis=new SequenceInputStream(enumeration);
		FileOutputStream fo=new FileOutputStream(new File(dir,filename));
		
		byte[] b=new byte[1024*1024];
		
		int len=0;
		//只要序列流讀取不返回-1,就將它寫入到輸出流指定檔案
		while((len=sis.read(b))!=-1){
			fo.write(b,0,len);
		}
		
		sis.close();fo.close();
	}

執行完畢:

重新變成了一個檔案,即截圖.bmp