玩过英雄联盟这款游戏的人一定会发现,每次下载的时候,你的下载目录中都会有好多个安装包,当时的我尚未接触编程,只是内心觉得可能是由于一个安装包太大了毕竟一个安装包现在都7、8个G了,分成好几个小的可能会下的快而且方便暂停.最近写的一个项目有许多的文件操作包括上传,下载,将excel数据导入到数据库或者将数据库数据导出下载等等.这不免让我思考,万一我有一个很大很大的excel文件或者别的格式的文件需要上传,那么这种情况下就可以对文件进行分割存储最后使用的时候再合并成为一个文件就可以了.
以下就是以本地的一个文件为例,进行读取,分割与合并操作的一个小demo
package com.example.demo.IOFile;
import java.io.*;
import java.util.ArrayList;
import java.util.List;
/**
* @author zhangqianwei
* @date 2021/8/24 13:36
* 使用IO流对大文件进行分割和分割后的合并
*/
public class fileSplit {
public static void main(String args[]) throws IOException {
String src = "H:\\work_order.sql"; //源文件路径
String destPath = "H:\\IOTest"; //分割文件存放路径
String[] srcPaths = splitFile(src,destPath); //分割后的文件路径
merge(destPath,srcPaths); //合并多个小文件成为一个大文件
}
/**
* 本地文件内容读取
* @param src
* @throws IOException
*/
public static void readLocalFile(String src) throws IOException {
File file = new File(src);
if (file.isFile() && file.exists()) {
//判断文件或目录是否存在
InputStream in = new FileInputStream(file);
try {
Reader reader = new InputStreamReader(in, "utf-8");
BufferedReader bufferedReader = new BufferedReader(reader);
String lineTxt = null;
List<String> list = new ArrayList<>();
//逐行读取文件内的信息
while ((lineTxt = bufferedReader.readLine()) != null) {
System.out.println(lineTxt);
list.add(lineTxt.replace(" ", ","));
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
catch (IOException e) {
System.out.println("异常:读取文件出错");
e.printStackTrace();
}
finally {
if (in != null){
in.close();
}
}
}
}
/**
* 大文件分割为多个小文件
* @param src
* @param destPath
* @throws FileNotFoundException
*/
public static String[] splitFile(String src,String destPath) throws FileNotFoundException {
File file = new File(src);
InputStream in = new FileInputStream(src);
Long fileSize = file.length();
if("".equals(src)||src==null||fileSize==0||"".equals(destPath)||destPath==null){
System.out.println("分割失败");
}
File srcFile = new File(src);//源文件
long srcSize = srcFile.length();//源文件的大小
long destSize = 1024;//目标文件的大小(分割后每个文件的大小设置为1KB)
int number = (int)(srcSize/destSize);
number = srcSize%destSize==0?number:number+1;//分割后文件的数目
//创建与小文件数量相同的字符串数组用来存储小文件的路径
String[] srcPaths =new String[number];
String fileName = src.substring(src.lastIndexOf("\\"));//源文件名
BufferedInputStream bis = null;//输入缓冲流
byte[] bytes = new byte[1024];//每次读取文件的大小为1KB
int len = -1;//每次读取的长度值
try {
in = new FileInputStream(srcFile);
bis = new BufferedInputStream(in);
for(int i=0;i<number;i++){
//设置分割后的文件扩展名为dat,文件名为:原文件名+原扩展名+编号+.dat
String destName = destPath+File.separator+fileName+"-"+i+".dat";
srcPaths[i] =destName;
OutputStream out = new FileOutputStream(destName);
BufferedOutputStream bos = new BufferedOutputStream(out);
int count = 0;
while((len = bis.read(bytes))!=-1){
bos.write(bytes, 0, len);//把字节数据写入目标文件中
count+=len;
if(count>=destSize){
break;
}
}
bos.flush();//刷新
bos.close();
out.close();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{
//关闭流
try {
if(bis!=null)bis.close();
if(in!=null)in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return srcPaths;
}
/**
* 文件合并
* 注意:在拼接文件路径时,一定不要忘记文件的跟路径,否则复制不成功
* @param destPath 目标目录
* @param srcPaths 源文件目录
*/
public static void merge(String destPath,String ... srcPaths){
//String ... 表示这个参数类型的对象可以存在0到多个
if(destPath==null||"".equals(destPath)||srcPaths==null){
System.out.println("路径不存在");
}
for (String string : srcPaths) {
if("".equals(string)||string==null)
System.out.println("合并失败");
}
//合并后的文件名
String name = srcPaths[0].substring(srcPaths[0].lastIndexOf("\\"));
String destName = name.substring(0, name.lastIndexOf("-"));
destPath = destPath+destName;//合并后的文件路径
File destFile = new File(destPath);//合并后的文件
OutputStream out = null;
BufferedOutputStream bos = null;
try {
out = new FileOutputStream(destFile);
bos = new BufferedOutputStream(out);
for (String src : srcPaths) {
File srcFile = new File(src);
InputStream in = new FileInputStream(srcFile);
BufferedInputStream bis = new BufferedInputStream(in);
byte[] bytes = new byte[1024];
int len = -1;
while((len = bis.read(bytes))!=-1){
bos.write(bytes, 0, len);
}
bis.close();
in.close();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{
//关闭流
try {
if(bos!=null)bos.close();
if(out!=null)out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}