1. 程式人生 > >分割流:例如,將一個圖片(53k)以10k為單位(單位的大小可隨著檔案的大小進行調整)進行分割,並將分割資訊以鍵值對的形式儲存到.properties檔案中。最後還可以將分割的檔案能夠完整的合併在一起

分割流:例如,將一個圖片(53k)以10k為單位(單位的大小可隨著檔案的大小進行調整)進行分割,並將分割資訊以鍵值對的形式儲存到.properties檔案中。最後還可以將分割的檔案能夠完整的合併在一起

將一個53k的圖片以10k為單位進行分割,最後再將分割的檔案合併到一起。

首先進行檔案的分割,這裡使用了兩種方法:

(1)其中splitFile(file)方法只是簡單地將圖片進行了分割。

(2)splitFile_2(file)方法除了將檔案進行分割,還將一些配置資訊進行了儲存。 切割檔案時,必須記錄被切割檔案的名稱以及切割出來的檔案的個數,以方便合併。這個資訊為了進行很好地描述,使用鍵值對的方式進行儲存,所以使用properties進行儲存。

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.util.Properties;

public class Demo4 {

	public static void main(String[] args) throws Exception {
		//建立一個檔案物件進行關聯
		File file=new File("d:\\16.jpg");
		
		//splitFile(file);
		
		splitFile_2(file);//以鍵值對的形式進行儲存
		
	}

	private static void splitFile_2(File file) throws Exception {
		
		//定義讀入流,與檔案相關聯
		FileInputStream fis=new FileInputStream(file);
		//定義緩衝區10k  圖片大小為53k
		byte[] buf=new byte[1024*10];
		int count=1;
		//建立一個目的
		FileOutputStream fos=null;//定義為null,因為不知道和誰關聯
		/*
		 * 切割檔案時,必須記錄被切割檔案的名稱以及切割出來的檔案的個數,以方便合併
		 * 這個資訊為了進行很好地描述,使用鍵值對的方式進行儲存,所以使用properties進行儲存
		 */
		
		Properties prop=new Properties();
		File dir=new File("d:\\partfiles");
		if(!dir.exists()){
			dir.mkdirs();
		}
		int len=0;
		while((len=fis.read(buf))!=-1){
			fos=new FileOutputStream(new File(dir,(count++)+".part"));
			fos.write(buf, 0, len);
			
		}
		//將被切割檔案的資訊儲存到properties中
		prop.setProperty("partcount", (--count)+"");//因為建立完檔案後,Count進行了自增操作,所以真正分割得到的檔案數應該再減去1
		prop.setProperty("filename", file.getName());
		//資料持久化
		fos=new FileOutputStream(new File(dir,count+".properties"));
		//將集合中的資料儲存到檔案中
		prop.store(fos, "file infos");
		fis.close();
		fos.close();
	}

	private static void splitFile(File file) throws Exception {
		//定義讀入流,與檔案相關聯
		FileInputStream fis=new FileInputStream(file);
		//定義緩衝區10k  圖片大小為53k
		byte[] buf=new byte[1024*10];
		//建立目的 1.part  2.part  3.part ...放到partfiles資料夾下
		FileOutputStream fos=null;
		File dir=new File("d:\\partfiles");
		//不存在則建立
		if(!dir.exists()){
			dir.mkdir();
		}
		int len=0;
		int count=1;//用於記錄1.part  2.part  3.part檔名前面的編號
		while((len=fis.read(buf))!=-1){
			fos=new FileOutputStream(new File(dir,(count++)+".part"));
			fos.write(buf, 0, len);
		}
		fos.close();
		fis.close();
		
	}

}

進行檔案的合併

使用SquenceInputStream類可以實現位元組輸入流的合併。
由於要使用SquenceInputStream類,所以需要將輸入流列表轉換為Enumeration(列舉)型別。
Collections工具類中的enumeration方法,將集合轉換為列舉型別。

//將分割的檔案合併到一起
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FilenameFilter;
import java.io.SequenceInputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.Properties;

public class Demo5 {

	public static void main(String[] args) throws Exception {
		//將分割的檔案進行合併
		File dir=new File("d:\\partfiles");
		mergeDir_2(dir);
	}

	private static void mergeDir_2(File dir) throws Exception {
		//從properties檔案中取出共分割了多少個檔案
		//通過過濾得到properties檔案
		File[] files=dir.listFiles(new SuffixFilter(".properties"));
		if(files.length!=1){
			throw new RuntimeException(dir+"該目錄下沒有properties副檔名的檔案或者檔案不唯一");
		}
		//記錄配置檔案物件
		File config=files[0];//因為過濾出來只有一個對應的檔案
		
		//獲取該檔案中的資訊
		Properties prop=new Properties();
		FileInputStream fis=new FileInputStream(config);
		prop.load(fis);//通過load將檔案中的資訊放到集合中
		String filename=prop.getProperty("filename");
		int count=Integer.parseInt(prop.getProperty("partcount"));
		//合併
		mergeFile(dir,filename,count);
	}

	private static void mergeFile(File dir, String filename, int count) throws Exception {
		
		ArrayList<FileInputStream> list=new ArrayList<>();
		//將分割得到的檔案放到集合中
		for(int x=1;x<=count;x++){//一共迴圈分割檔案的個數次
			list.add(new FileInputStream(new File(dir,x+".part")));
			
		}
		Enumeration<FileInputStream> en=Collections.enumeration(list);//將集合轉換為列舉型別
		SequenceInputStream sis=new SequenceInputStream(en);
		FileOutputStream fos=new FileOutputStream(new File(dir,filename));//將合併流中的資訊輸出到目的檔案中
		byte[] buf=new byte[1024];
		int len=0;
		while((len=sis.read(buf))!=-1){
			fos.write(buf, 0, len);
		}
		fos.close();
		sis.close();
	}
}
class SuffixFilter implements FilenameFilter{
	private String suffix;
	public SuffixFilter(String suffix) {
		this.suffix=suffix;
	}
	@Override
	public boolean accept(File dir, String name) {
		
		return name.endsWith(suffix);
	}
	
}