java IO流_167_文件合并_练习3

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
	
}

}
//结果--------------------------------------
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值