分割流:例如,將一個圖片(53k)以10k為單位(單位的大小可隨著檔案的大小進行調整)進行分割,並將分割資訊以鍵值對的形式儲存到.properties檔案中。最後還可以將分割的檔案能夠完整的合併在一起
阿新 • • 發佈:2018-12-06
將一個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); } }