java 大文件分割与组装

  注意:这里说的就是“物理分割”,是真的会把文件分开
  不多说,直接上代码

1
import java.io.File; 2 import java.io.FileInputStream; 3 import java.io.FileOutputStream; 4 import java.io.IOException; 5 import java.io.InputStream; 6 import java.io.OutputStream; 7 8 /* 9 *功能:将800M以上大文件(不分类型)切割成为2M/ per part 10 *@date:2018/7/9/23:31 11 *@author:Yoci 12 */ 13 public class GeAndZhuang{ 14 public static void sCut(File f, int partSize) { 15 if(f.length()>2048*1024) { 16 System.out.println("启动成功"); 17 int count = (int)(Math.ceil(f.length() / partSize))+1;//块数 18 System.out.println("块数"+count); 19 try { 20 /**创建输入输出流对象*/ 21 InputStream inf = new FileInputStream(f); 22 System.out.println("输入流启动成功"); 23 OutputStream[] outf = new FileOutputStream[count]; 24 System.out.println("输出流启动成功:"+outf.length); 25 /**创建文件夹,存储各小块文件*/ 26 int no = f.getName().lastIndexOf("."); 27 String str = f.getParent()+"\"+f.getName().substring(0, no );/**目录路径*/ 28 File dirfile = new File(str); 29 if(!dirfile.exists()) { 30 dirfile.mkdirs(); 31 } 32 /**创建各小块文件并命名*/ 33 File[] dir_f = new File[count]; 34 System.out.println("数组创建成功:"+dir_f.length); 35 /**获取文件类型*/ 36 String fName = f.getName(); 37 String fPattern = fName.substring(fName.lastIndexOf("."), fName.length()); 38 System.out.println("文件类型获取成功:"+fPattern); 39 for(int j=0; j<count; j++) { 40 String newPath = str+"\"+f.getName().substring(0, no)+"-"+j+fPattern; 41 dir_f[j] = new File(newPath); 42 outf[j] = new FileOutputStream(dir_f[j]); 43 } 44 /**写入各块内容*/ 45 int s,m=0, n=2*1024*1024; 46 byte[] buffer = new byte[n]; 47 s = inf.read(buffer, 0, n); 48 while(s != -1&& m<count) { 49 if(dir_f[m].length() < 2048*1024) { 50 outf[m].write(buffer, 0, n); 51 s = inf.read(buffer, 0, n); 52 } 53 if(dir_f[m].length() == 2048*1024){ 54 outf[m].close(); 55 m = m+1; 56 int off = (int)(f.length()-m*2048*1024); 57 if(off<2048*1024) { 58 outf[m].write(buffer, 0, off); 59 outf[m].close(); 60 break; 61 } 62 } 63 } 64 inf.close(); 65 f.delete(); 66 } 67 catch(IOException ioe) { 68 System.out.println("IO 异常"); 69 } 70 catch(IndexOutOfBoundsException ine) { 71 System.out.println("数组越界 异常"); 72 } 73 catch(Exception e) { 74 System.out.println("异常"); 75 } 76 } 77 else { 78 System.out.println("启动失败"); 79 } 80 } 81 public static void divide( String fPath ) { 82 File f = new File(fPath); 83 /**文件存在*/ 84 if(f.exists()){ 85 /**是单个文件*/ 86 if(f.isFile() && f.length() > 2048*1024) { 87 /**调用单文件分割方法*/ 88 sCut(f, 2048*1024); 89 } 90 /**是目录*/ 91 else if(f.isDirectory() && f.length() > 2048*1024) { 92 /**目录文件数组化*/ 93 File[] dir = f.listFiles(); 94 95 for(int i=0; i<dir.length; i++) { 96 if(dir[i].exists() && dir[i].length() > 2048*1024){ 97 if(dir[i].isFile()) { 98 sCut(dir[i], 2048*1024); 99 } 100 else if(dir[i].isDirectory() && dir[i].length() > 2048*1024) { 101 divide(dir[i].getAbsolutePath()); 102 } 103 } 104 else { 105 System.out.println(dir[i].getAbsolutePath()+ "文件或目录较小,无需处理!"); 106 } 107 } 108 } 109 } 110 else { 111 System.out.println(fPath + " 不存在,分割失败!"); 112 } 113 } 114 /** 115 *小块组装/还原 116 *@param fPath 待组装的文件/目录绝对路径 117 *@return null 118 *思路:扫描文件/目录,当遇到内部文件以 文件夹名 命名且予以编号时,合并文件夹内所有文件并覆盖此文件夹 119 *result:文件/目录属性与分割前相同 120 */ 121 public static void pack( String fPath ) { 122 File f = new File(fPath); 123 boolean flag = false; 124 int t, num = 0; 125 if(f.exists()){ 126 if(f.isDirectory()) { 127 File[] dir = f.listFiles(); 128 for(t=0; t<dir.length; t++) { 129 if(dir[t].isFile()) { 130 if(dir[t].getName().lastIndexOf("-") != -1) { 131 String cutName = dir[t].getName().substring(0, dir[t].getName().lastIndexOf("-")); 132 if(f.getName().compareTo(cutName) == 0) { 133 flag = true; 134 num += 1; 135 } 136 else { 137 flag = false; 138 } 139 } 140 } 141 else if(dir[t].isDirectory()) { 142 pack(dir[t].getAbsolutePath()); 143 } 144 } 145 /**组装开始*/ 146 if(flag == true && num == dir.length) { 147 try { 148 /**重新构建路径=文件夹路径+后缀*/ 149 String dirName = dir[0].getName(); 150 int begin = dirName.lastIndexOf("."); 151 String coverPath = f.getAbsolutePath() + dirName.substring(begin, dirName.length()); 152 File coverFile = new File(coverPath); 153 154 /**构建输入输出流: 155 * 输入流:packIn dir 文件夹中的编号文件 156 * 输出流:packOut coverFile 157 */ 158 OutputStream packOut = new FileOutputStream(coverFile, true); 159 int sizeOfDir = dir.length; 160 for(t=0; t< sizeOfDir; t++) 161 { 162 for(int k=0; k<sizeOfDir; k++) { 163 int b = dir[k].getName().lastIndexOf("-"); 164 int e = dir[k].getName().lastIndexOf("."); 165 /**找到与 序号匹配的 文件 写入*/ 166 if(dir[k].getName().substring(b+1, e) .compareTo(String.valueOf(t))==0) { 167 //System.out.println(t+" "+ dir[k].getName().substring(b+1, e)); 168 InputStream packIn = new FileInputStream(dir[k]); 169 int s, n=2*1024*1024; 170 byte[] buffer = new byte[n]; 171 s = packIn.read(buffer, 0, n); 172 if(dir[k].length()==2*1024*1024) { 173 packOut.write(buffer, 0, n); 174 packIn.close(); 175 dir[k].delete(); 176 } 177 else { 178 int end = (int)dir[k].length(); 179 packOut.write(buffer, 0, end); 180 packIn.close(); 181 dir[k].delete(); 182 } 183 break; 184 } 185 } 186 } 187 packOut.close(); 188 System.out.println("文件数:"+dir.length); 189 f.delete(); 190 } 191 catch(Exception e) { 192 System.out.println("异常"); 193 } 194 } 195 } 196 } 197 } 198 public static void main(String[] args) { 199 String path = "F:\2221511550\Videos\26.20 - 副本.mp4";//要切割的文件/目录路径 200 divide(path);//切割 201 pack("F:\2221511550\Videos\26.20 - 副本");//组装(给出路径) 202 } 203 }
原文地址:https://www.cnblogs.com/yocichen/p/9307558.html