首页 > 编程语言 >java实现大文件的拆分与合并

java实现大文件的拆分与合并

时间:2022-08-14 23:24:16浏览次数:48  
标签:文件 java String 合并 return 拆分 length File new

前言

我需要把一个大文件上传到网盘上,由于网盘禁止上传大于4G的文件,所以我想通过Java程序来把大文件分割为小文件后,再上传,等需要的时候,通过程序把文件进行合并即可。

一、废话少说,直接上代码

代码如下:

  1 package com.xm.file;
  2 
  3 import java.io.*;
  4 import java.util.Arrays;
  5 import java.util.Date;
  6 import java.util.List;
  7 import java.util.stream.Collectors;
  8 
  9 /**
 10  * 1.把大文件按照指定大小分割成多个小文件
 11  * 2.把多个小文件分割为大文件
 12  * 测试用例@com.xm.FileSplitAndCombineTest
 13  */
 14 public class FileSplitAndCombine {
 15 
 16     private static int THOUSAND_TWENTY_FOUR= 1024; // one thousand and twenty-four
 17 
 18 
 19 
 20     /**
 21      * 把大文件拆分为多个小文件
 22      *
 23      * @param sourcePath 需要被拆分的文件路径
 24      * @param desPath    拆分后的文件应该存放的文件路径
 25      * @param newName    每一个小文件名
 26      */
 27     public static void splitFile(String sourcePath, String desPath, String newName) {
 28 
 29         try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream(new File(sourcePath)))) {
 30             for (int i = 0; ; i++) {
 31                 String filePath = desPath + File.separatorChar +newName+"_" +i;
 32                 if (singleSplitFile(bis, filePath, THOUSAND_TWENTY_FOUR)) break;
 33             }
 34         } catch (IOException e) {
 35             e.printStackTrace();
 36         }
 37     }
 38 
 39 
 40     /**
 41      * @param bis 输入流
 42      * @param filePath       新文件存储的文件夹路径
 43      * @param partitionSize 每个文件的大小 单位MB
 44      * @throws IOException
 45      */
 46     private static boolean singleSplitFile(BufferedInputStream bis, String filePath,int partitionSize) throws IOException {
 47         int length = partitionSize * THOUSAND_TWENTY_FOUR * THOUSAND_TWENTY_FOUR;
 48         byte[] buffer = new byte[THOUSAND_TWENTY_FOUR];
 49         int tempLength;
 50 
 51         System.out.println(nowTime() + "----->>>> begin split " + filePath);
 52         try (BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(new File(filePath)))) {
 53             while ((tempLength = bis.read(buffer)) != -1) {
 54                 bos.write(buffer, 0, tempLength);
 55                 if ((length = length - tempLength) <= 0) break;
 56             }
 57         }
 58         System.out.println(nowTime() + "<<<<----- yet finish split" + filePath);
 59 
 60         return tempLength < 0;
 61     }
 62 
 63     /**
 64      * 把指定文件夹内的文件合并为一个文件
 65      *
 66      * @param sourcePath 需要被合并的文件所在的文件中路径
 67      * @param desPath    合并后的文件存放位置
 68      */
 69     public static void combineFile(String sourcePath, String desPath) {
 70 
 71         List<String> sortedFileNames = sortFilesName(sourcePath);
 72         if (sortedFileNames == null) {
 73             System.out.println(sourcePath+"路径下不存在文件夹");
 74             return;
 75         }
 76 
 77         try (BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(new File(desPath)))) {
 78             for (String sortedFileName : sortedFileNames) {
 79                 copyFile(bos, sourcePath + File.separatorChar + sortedFileName);
 80             }
 81             System.out.println("all finish...");
 82         } catch (IOException e) {
 83             e.printStackTrace();
 84         }
 85     }
 86 
 87     /**
 88      * 把目标文件合并到输出流中
 89      *
 90      * @param bos 缓冲输出流
 91      * @param des 目标文件路径
 92      * @throws IOException
 93      */
 94     private static void copyFile(BufferedOutputStream bos, String des) throws IOException {
 95 
 96         try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream(new File(des)))) {
 97             System.out.println(nowTime()+ "------>>>>"+des + "开始合并");
 98             byte[] bytes = new byte[1024];
 99             int length;
100             while ((length = bis.read(bytes)) != -1) {
101                 bos.write(bytes, 0, length);
102             }
103             System.out.println(nowTime()+ "<<<<------"+des + "合并完成");
104         }
105     }
106 
107     /**
108      * 对指定文件夹内的文件名进行排序 (增序)
109      *
110      * @param fileDir
111      * @return
112      */
113      private static List<String> sortFilesName(String fileDir) {
114         File file = new File(fileDir);
115         File[] files = file.listFiles();
116         if (null == files || files.length == 0) {
117             return null;
118         }
119         Pattern compile = Pattern.compile("^.+_\\d+$");
120         return Arrays.stream(files).filter(file1 -> {
121             if (file1.isDirectory()){
122                 System.out.println("waring: "+ file1.getName() +"不是一个文件");
123                 return false;
124             }
125             String file1Name = file1.getName();
126             Matcher matcher = compile.matcher(file1Name);
127             if (!matcher.find()){
128                 System.out.println("waring:文件名 "+file1Name+"不符合 文件名_数字的命名规范");
129                 return false;
130             }
131             return true;
132         }).map(File::getName)
133                 .sorted((fileName1,fileName2)->{
134                     String[] split1 = fileName1.split("_");
135                     String[] split2 = fileName2.split("_");
136                     return Integer.parseInt(split1[split1.length - 1])-Integer.parseInt(split2[split2.length - 1]);
137                 }).collect(Collectors.toList());
138     }
139     
140     private static String nowTime(){
141        return new Date().toLocaleString();
142     }
143 }

二.测试用例

代码如下:

 1 package com.xm;
 2 
 3 import com.xm.file.FileSplitAndCombine;
 4 
 5 
 6 public class FileSplitAndCombineTest {
 7     public static void main(String[] args) {
 8        //文件分割
 9         splitTest();
10         //文件合并
11         combineTest();
12     }
13 
14     private static void splitTest() {
15         String sourcePath = "E:\\fileSplitTest\\source.zip";
16         String desPath = "E:\\fileSplitTest";
17         String newName = "split";
18 
19         FileSplitAndCombine.splitFile(sourcePath, desPath, newName);
20     }
21 
22     private static void combineTest() {
23         String desPath  = "E:\\fileSplitTest\\combine.zip";
24         String sourcePath = "E:\\fileSplitTest";
25 
26         FileSplitAndCombine.combineFile(sourcePath, desPath);
27     }
28 }

当切割的文件个数大于10的时候会出现文件损害的问题。原因时因为没有按照原来分割的顺序切割文件,出错代码在sortFilesName(String fileDir)方法中。可通过如下方式修改

 1 private static List<String> sortFilesName(String fileDir) {
 2         File file = new File(fileDir);
 3         File[] files = file.listFiles();
 4         if (null == files || files.length == 0) {
 5             return null;
 6         }
 7         Pattern compile = Pattern.compile("^.+_\\d+[csdnCommentCode]quot;);
 8         return Arrays.stream(files).map(File::getName)
 9                 .sorted((fileName1,fileName2)->{
10                     String[] split1 = fileName1.split("_");
11                     String[] split2 = fileName2.split("_");
12                     return Integer.parseInt(split1[split1.length - 1])-Integer.parseInt(split2[split2.length - 1]);
13                 }).collect(Collectors.toList());
14     }

 

标签:文件,java,String,合并,return,拆分,length,File,new
From: https://www.cnblogs.com/mingruifeng/p/16586671.html

相关文章

  • javaSE的补充
    1instanceOf(1)用于比较两个对象是否相等XinstanceOfY用于比较X,Y是否存在父子关系(2)子类转换为父类,可能为丢失子类自己独自拥有的方法2Static修饰符的补充理解......
  • java12 - 封装+继承+多态
    封装该露的露,该藏的藏我们程序设计要追求“高内聚,低耦合”。高内聚就是类的内部数据操作细节自己完成,不允许外部干涉;低耦合:仅暴露少量的方法给外部使用。封装(数据......
  • Java特性和优势
    Java特性和优势简单性面向对象可移植性(WriteOnce,RunAnywhere)高性能分布式动态性(反射)多线程安全性(异常机制,捕获异常)健壮性Java的三大版本JavaSE:标准版(桌面......
  • Java一次计算简易计算器
    小白简易计算器第一次尝试写代码publicclassCalculator{publicstaticvoidmain(String[]args){//创建扫描对象Scannerscanner=newS......
  • 《Effective Java》第54条:返回零长度的数组或者集合,而不是null
    《EffectiveJava》第54条:返回零长度的数组或者集合,而不是null一、问题如果一个方法返回类型是list,如果结果为空的情况下返回null的情况并不少见,如下:publicclassShop_......
  • Java Script了解
    JavaScript了解诞生于1995年LiveScript更名为JavaScript(Netscape(网景公司)出品)JavaScript的概述JavaScript是一个轻量级的语句,他是单线程的语言(一个线程解析);他是一......
  • JavaScript关于cookie
        1.http和httpshttp,https都是网络传输协议是用于网络相关传输,http走的是明文传输,https走的密文传输(内部采用对称加密以及非对称加密)。对应的https安全性......
  • Java中Get和Post的使用
    原文链接1Get请求数据项目地址:https://github.com/Snowstorm0/learn-get-post1.1Controller文件名MyController,内容为:@RestController@RequestMapping("/homepage"......
  • 自学java第10天之接口思想
    图:1.2.3.文字解释: ......
  • JAVA基础环境 一、JDK安装与环境
    JAVA开发者所需的基础环境变量注意*以下内容请在Windows企业版或专业版配置,以免遇到不必要的麻烦一、jdk配置1.jdk下载jdk下载需要去Oracle官网下载,地址是https://www......