文件的分割與合併

  1 package service;
  2 import service.oss.FileUtil;
  3 
  4 import java.io.BufferedInputStream;
  5 import java.io.BufferedOutputStream;
  6 import java.io.File;
  7 import java.io.FileInputStream;
  8 import java.io.FileNotFoundException;
  9 import java.io.FileOutputStream;
 10 import java.io.IOException;
 11 import java.io.InputStream;
 12 import java.io.RandomAccessFile;
 13 import java.io.SequenceInputStream;
 14 import java.util.ArrayList;
 15 import java.util.List;
 16 import java.util.Vector;
 17  
 18 public class SplitFile {
 19     //文件的路徑
 20     private String filePath;
 21     //文件名
 22     private String fileName;
 23     //文件大小
 24     private long length;
 25     //塊數
 26     private int size;
 27     //每塊的大小
 28     private long blockSize;
 29     //分割後的存放目錄
 30     private String destBlockPath;
 31     //每塊的名稱
 32     private List<String> blockPath;
 33     
 34     public SplitFile(){
 35         blockPath = new ArrayList<String>();
 36     }
 37     public SplitFile(String filePath,String destBlockPath){
 38         this(filePath,destBlockPath,1024);        
 39     }
 40     public SplitFile(String filePath,String destBlockPath,long blockSize){
 41         this();
 42         this.filePath= filePath;
 43         this.destBlockPath =destBlockPath;
 44         this.blockSize=blockSize;
 45         init();
 46     }
 47     
 48     /**
 49      * 初始化操作 計算 塊數、確定文件名
 50      */
 51     public void init(){
 52         File src =null;
 53         //健壯性
 54         if(null==filePath ||!(((src=new File(filePath)).exists()))){
 55             return;
 56         }
 57         if(src.isDirectory()){
 58             return ;
 59         }
 60         //文件名
 61         this.fileName =src.getName();
 62         
 63         //計算塊數 實際大小 與每塊大小
 64         this.length = src.length();
 65         //修正 每塊大小
 66         if(this.blockSize>length){
 67             this.blockSize =length;
 68         }
 69         //確定塊數        
 70         size= (int)(Math.ceil(length*1.0/this.blockSize));
 71         //確定文件的路徑
 72         initPathName();
 73     }
 74     
 75     private void initPathName(){
 76         for(int i=0;i<size;i++){
 77             this.blockPath.add(destBlockPath+"/"+this.fileName+".part"+i);
 78         }
 79     }
 80     
 81     /**
 82      * 文件的分割
 83      * 0)、第幾塊
 84      * 1、起始位置
 85      * 2、實際大小
 86      * @param
 87      */
 88     public void split(){    
 89         long beginPos =0;  //起始點
 90         long actualBlockSize =blockSize; //實際大小        
 91         //計算所有塊的大小、位置、索引
 92         for(int i=0;i<size;i++){
 93             if(i==size-1){ //最後一塊
 94                 actualBlockSize =this.length-beginPos;
 95             }            
 96             spiltDetail(i,beginPos,actualBlockSize);
 97             beginPos+=actualBlockSize; //本次的終點,下一次的起點
 98         }
 99         
100     }
101     /**
102      * 文件的分割 輸入 輸出
103      * 文件拷貝
104      * @param idx 第幾塊
105      * @param beginPos 起始點
106      * @param actualBlockSize 實際大小
107      */
108     private void spiltDetail(int idx,long beginPos,long actualBlockSize){
109         //1、創建源
110         File src = new File(this.filePath);  //源文件
111         File dest = new File(this.blockPath.get(idx)); //目標文件
112         //2、選擇流
113         RandomAccessFile raf = null;  //輸入流
114         BufferedOutputStream bos=null; //輸出流
115         try {
116             raf=new RandomAccessFile(src,"r");
117             bos =new BufferedOutputStream(new FileOutputStream(dest));
118             //讀取文件
119             raf.seek(beginPos);
120             //緩衝區
121             byte[] flush = new byte[1024];
122             //接收長度
123             int len =0;
124             while(-1!=(len=raf.read(flush))){                
125                 if(actualBlockSize-len>=0){ //查看是否足夠
126                     //寫出
127                     bos.write(flush, 0, len);
128                     actualBlockSize-=len; //剩餘量
129                 }else{ //寫出最後一次的剩餘量
130                     bos.write(flush, 0, (int)actualBlockSize);
131                     break;
132                 }
133             }
134         } catch (FileNotFoundException e) {
135             e.printStackTrace();
136         } catch (IOException e) {
137             e.printStackTrace();
138         }finally{
139             FileUtil.close(bos,raf);
140         }
141     }
142     /**
143      * 文件的合併
144      */
145     public void merge(String destPath){
146         //創建源
147         File dest =new File(destPath);
148         //選擇流
149         BufferedOutputStream bos=null; //輸出流
150         SequenceInputStream sis =null ;//輸入流
151         //創建一個容器
152         Vector<InputStream> vi = new Vector<InputStream>();        
153         try {
154             for (int i = 0; i < this.blockPath.size(); i++) {
155                 vi.add(new BufferedInputStream(new FileInputStream(new File(this.blockPath.get(i)))));
156             }    
157             bos =new BufferedOutputStream(new FileOutputStream(dest,true)); //追加
158             sis=new SequenceInputStream(vi.elements());            
159             //緩衝區
160             byte[] flush = new byte[1024];
161             //接收長度
162             int len =0;
163             while(-1!=(len=sis.read(flush))){                        
164                 bos.write(flush, 0, len);
165             }
166             bos.flush();
167             FileUtil.close(sis);
168         } catch (Exception e) {
169         }finally{
170             FileUtil.close(bos);
171         }        
172     }
173     /**
174      * @param args
175      */
176     public static void main(String[] args) {
177         //1024 * 30 表示按照每塊30Kb大小分割
178         SplitFile split = new SplitFile("C:\\Users\\Spring\\Desktop\\二期(後臺)需求20191209(1).doc","C:/123/",1024);
179         
180         System.out.println(split.size);
181 //
182 //        split.split();
183         
184         split.merge("C:/123/logFile.doc");
185         
186     }
187  
188 }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章