package IO流_167_文件分割与合并_文件合并;
import java.io.BufferedInputStream;
/**
- 面向对象编程
*/
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.ArrayList;
import java.util.List;
public class SplitFile {
private String filePath;//文件路径
private int size;//块数
private long blockSize;//每块大小
private List blockPath;//每块存储的名称
private String fileName;//每块名称
private long length;//文件大小
private String destBlockPath;//分割后的存放目录
//构造器
public SplitFile() {
blockPath = new ArrayList<String>();
}
public SplitFile(String filePath,String destBlockPath) {//构造器相互调用
//this(filePath,1024,destBlockPath);//调用SplitFile(String filePath, long blockSize)
//其他文件名的分割与合并; 调整下位置
this(filePath,destBlockPath,1024);
}
/*public SplitFile(String filePath, long blockSize,String destBlockPath) {
this(); //调用 SplitFile()
this.filePath = filePath;
this.blockSize = blockSize;
this.destBlockPath = destBlockPath;
init();//调用
}*/
//其他文件名的分割与合并; 调整下位置
public SplitFile(String filePath,String destBlockPath, long blockSize) {
this(); //调用 SplitFile()
this.filePath = filePath;
this.blockSize = blockSize;
this.destBlockPath = destBlockPath;
init();//调用
}
//初始化操作 ;计算块数及确定文件名
public void init(){
File src = null;
//程序的健壮性;判断文件是否为空或者是否存在
if(null==filePath||!((src=new File(filePath)).exists())){
return;
}
if(src.isDirectory()){//判断是否为文件夹
return;
}
//计算块数;判断实际大小与每块大小
this.fileName = src.getName();
this.length= src .length();
//修正每块的大小
if(this.blockSize>length){//如果this.blockSize大小>实际的大小;则改成实际大小
this.blockSize=length;
}
//确定块数;相同整数相除有可能变为0;所有乘1.0;
size = (int) (Math.ceil(length*1.0/this.blockSize)); //强转型
initPathName();//确定文件路径
}
//获取每块的名称
private void initPathName(){
for(int i=0;i<size;i++){
this.blockPath.add(destBlockPath+"/"+this.fileName+".part"+i);
}
}
/*
* 分割后文件存放的目录
* 1.第几块
* 2.起始位置
* 3.实际大小
*/
public void split(){
long beginPos = 0;//起始点为0;
long actualBlockSize = blockSize;//actualBlockSize实际大小=原来的blockSize
//计算所有块的大小,位置,索引
for(int i=0;i<size;i++){
//判断
if(i==size-1){//最后一块
actualBlockSize = this.length-beginPos;
}
splitDetail(i,beginPos,actualBlockSize);
beginPos +=actualBlockSize;//本一次终点也是下一次起点
}
}
/**
* 文件分割 ;输入,输出,文件拷贝
* @param idx;第几块
* @param beginPos;起始点
* @param actualBlockSize;实际大小
*/
private void splitDetail(int idx,long beginPos,long actualBlockSize){
File src = new File(this.filePath);//创建源
File dest = new File(this.blockPath.get(idx));//目的地
RandomAccessFile raf = null; //输入流
BufferedOutputStream bos = null;//输出流文件的拷贝
try {
raf = new RandomAccessFile(src,"r");//只读模式'r'
bos = new BufferedOutputStream(new FileOutputStream(dest));
//读取文件
raf.seek(beginPos);//确定起始位置
//缓冲区
byte[] flush = new byte[1024];
//接收长度
int len = 0;
//循环读取
while(-1!=(len=raf.read(flush))){
//判断; 控制大小,
if(actualBlockSize-len>=0){//查看长度是否足够写出
//写出
bos.write(flush, 0, len);
actualBlockSize -=len; //读取一部分就去掉一部分;最后就是剩余量
}else{//如果长度不够写出,就直接写出剩余部分
bos.write(flush, 0, (int) actualBlockSize);
break;//结束循环
}
}
//注意这个不能忘 否则分割后的文件内容为空******************
bos.flush();//强制刷出
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{
CloseUtil.closeIO(bos, raf);
}
}
/**
* 文件的合并
* @param destPath
*/
public void merge(String destPath){
// 创建源
File dest = new File(destPath);
//选择流
BufferedOutputStream bos = null;//输出流
try {
bos = new BufferedOutputStream(new FileOutputStream(dest,true));//true是追加;false是覆盖
BufferedInputStream bis = null;//输入流
for(int i=0;i<this.blockPath.size();i++){//blockPath每块存储的名称
bis = new BufferedInputStream(new FileInputStream( new File(this.blockPath.get(i))));//处理异常
//缓冲区
byte[] flush = new byte[1024];
//接收长度
int len =0;
while(-1!=(len= bis.read(flush))){//处理异常
//查看内容是否写出
System.out.println(new String(flush, 0, len));
bos.write(flush, 0, len);
}
bos.flush();
CloseUtil.closeIO(bis);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{
CloseUtil.closeIO(bos);
}
}
public static void main(String[] args) {
//SplitFile file = new SplitFile("E:/xp/2020/test/char.java",50,"E:/xp/2020");
//其他文件名的分割与合并
SplitFile file = new SplitFile("E:/xp/2020/学员设置(2020).xls","E:/xp/2020",51);
//System.out.println(file.size);
//file.split("E:/xp/2020");
//其他文件名的分割与合并;先分割后合并
file.split();
file.merge("E:/xp/2020/test.xls");
}
}
//----------------------------------------------------------
package IO流_167_文件分割与合并_文件合并;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.RandomAccessFile;
public class CloseUtil {
public static void closeIO(BufferedOutputStream bos, RandomAccessFile raf) {
// TODO Auto-generated method stub
}
public static void closeIO(BufferedInputStream bis) {
// TODO Auto-generated method stub
}
public static void closeIO(BufferedOutputStream bos) {
// TODO Auto-generated method stub
}
}
//结果--------------------------------------