文件分割与合并

package com.cyj.Other;

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 String fileName;
    private long length; //文件的大小
	
	//定义每块的大小,块数
	private long blockSize;
	private int num;
	
	//每块的名称,List接口实现
	private List<String> blockName;
	
	public SplitFile() {
		blockName = new ArrayList<String>(); //泛型
	}
	
	public SplitFile(String filePath){
		this(filePath,1024);  //调用下面的构造器
	}
	
	public SplitFile(String filePath,int blockSize){
		this(); //调用第一个无参的构造器
		this.filePath = filePath;
		this.blockSize = blockSize;
		
		init(); //声明完函数之后,直接完成计算块的大小和数量
	}
	
	
	/**
	 * 文件分割的初始化操作,设置分割的的大小,个数,名称
	 * @param args
	 */
	
	public void init() {
		
		//先需要判断文件是否存在
		File src = null;
		
		if(null == filePath || !(((src = new File(filePath)).exists()))){
			System.out.println("文件不存在");
			return;
		}
		
		if(src.isDirectory()) {
			return;
		}
		//块的名字的确定
		this.fileName = src.getName();
		
		//操作
		 this.length = src.length();
		
		//判断大小是否合理
		if(this.blockSize>length) {
			this.blockSize = length;  //如果每块的大小比文件的实际大小还要大,没有意义换个大小
		}
		
		//确定块数,然后为分块命名 
		num = (int)(Math.ceil(length*1.0/this.blockSize)); //Math.ceil()大于最小整数,1.0是为了避免不足1当为0处理 	
	}
	
	private void initPathName(String destPath) {
		for(int i=0; i<num; i++) {
			this.blockName.add(destPath+"/"+this.fileName+".part"+i);
		}
	}
	
	
	
	/**
	 * 初始操作后的分割
	 * 步骤:
	 * 1 确定在第几块
	 * 2 块开始的位置
	 * 3 块的实际的大小
	 * 
	 * 功能:计算每个块的大小,位置,索引
	 * @param args
	 * @throws IOException 
	 */
	
	private void split(String dastPath) throws IOException {
		
		//确定文件的路径
		initPathName(dastPath);	
		
		long beginPos = 0;  //块的起始的位置
		long actualBlockSize = blockSize; //块的实际大小,最后一块是不确定的
		
		for(int i=0; i<num ;i++) {
			if(i == num-1) {
				actualBlockSize = this.length - beginPos;
			}
			splitWay(i,beginPos,actualBlockSize);
			beginPos += actualBlockSize;  //本次终点就是下个位置的起点
		}
		
	}
	
	
	/**
	 * 文件的分割
	 * @param i
	 * @param beginPos
	 * @param actualBlockSize
	 * @throws IOException 
	 */
	
	private void splitWay(int idnum, long beginPos, long actualBlockSize) throws IOException {


		//建立联系
		File src = new File(this.filePath);
		File dest = new File(this.blockName.get(idnum));
		
		//选择流
		RandomAccessFile raf = null;
		BufferedOutputStream bos = null;
		
		try {  //这里如果抛出异常,前面一系列调用都要抛出异常
			
			raf = new RandomAccessFile(src,"r");
			bos = new BufferedOutputStream(new FileOutputStream(dest));
			
			//读取文件
			try {
				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,len);
						break; //不然会读到超出部分
					}		
					
				}
			
				
			} catch (IOException e) {
				e.printStackTrace();
				System.out.println("文件读取失败");
			}
			
			
		} catch (FileNotFoundException e) {
			e.printStackTrace();
			System.out.println("文件找不到");
		}
		
			bos.close();
			raf.close();
	
	}
	
	
	/**
	 * 文件的合并
	 * @param args
	 * @throws IOException
	 */
	
	public void mergeFile(String destPath) throws IOException {
		//建立联系
		File dest = new File(destPath);
		
		//选择流
		BufferedInputStream bis = null;
		
		BufferedOutputStream bos = null;
		bos = new BufferedOutputStream(new FileOutputStream(dest,true));//文件的追加读取
		
		for(int i=0; i<this.blockName.size(); i++) {
			try {				
				bis = new BufferedInputStream(new FileInputStream(this.blockName.get(i)));
				
				//读取文件三板斧
				byte[] flush = new byte[1024];//缓冲区
				int len = 0;//接收长度
				
				while(-1 != (len=bis.read(flush))){//读取
					
					bos.write(flush, 0, len);
				}
				
				bos.flush();//强制刷出
				bis.close();
				
			} catch (FileNotFoundException e) {
				e.printStackTrace(); 
				System.out.println("文件没有找到");
			}finally {
				bos.close();
			}
		}
	}
	


	public static void main(String[] args) throws IOException {
	SplitFile file = new SplitFile("E:\\爱情公寓全集\\浙江.txt",25);	//以为长度大小分割
		
	System.out.println(file.num);
	//file.split("E:\\爱情公寓全集"); //先单独执行分割,再执行合并
	
	file.mergeFile("E:\\爱情公寓全集\\浙江2.txt");
	
	}
}
	//建立联系
	private String filePath;
	private String fileName;
    private long length; //文件的大小
	
	//定义每块的大小,块数
	private long blockSize;
	private int num;
	
	//每块的名称,List接口实现
	private List<String> blockName;
	
	public SplitFile() {
		blockName = new ArrayList<String>(); //泛型
	}
	
	public SplitFile(String filePath){
		this(filePath,1024);  //调用下面的构造器
	}
	
	public SplitFile(String filePath,int blockSize){
		this(); //调用第一个无参的构造器
		this.filePath = filePath;
		this.blockSize = blockSize;
		
		init(); //声明完函数之后,直接完成计算块的大小和数量
	}
	
	
	/**
	 * 文件分割的初始化操作,设置分割的的大小,个数,名称
	 * @param args
	 */
	
	public void init() {
		
		//先需要判断文件是否存在
		File src = null;
		
		if(null == filePath || !(((src = new File(filePath)).exists()))){
			System.out.println("文件不存在");
			return;
		}
		
		if(src.isDirectory()) {
			return;
		}
		//块的名字的确定
		this.fileName = src.getName();
		
		//操作
		 this.length = src.length();
		
		//判断大小是否合理
		if(this.blockSize>length) {
			this.blockSize = length;  //如果每块的大小比文件的实际大小还要大,没有意义换个大小
		}
		
		//确定块数,然后为分块命名 
		num = (int)(Math.ceil(length*1.0/this.blockSize)); //Math.ceil()大于最小整数,1.0是为了避免不足1当为0处理 	
	}
	
	private void initPathName(String destPath) {
		for(int i=0; i<num; i++) {
			this.blockName.add(destPath+"/"+this.fileName+".part"+i);
		}
	}
	
	
	
	/**
	 * 初始操作后的分割
	 * 步骤:
	 * 1 确定在第几块
	 * 2 块开始的位置
	 * 3 块的实际的大小
	 * 
	 * 功能:计算每个块的大小,位置,索引
	 * @param args
	 * @throws IOException 
	 */
	
	private void split(String dastPath) throws IOException {
		
		//确定文件的路径
		initPathName(dastPath);	
		
		long beginPos = 0;  //块的起始的位置
		long actualBlockSize = blockSize; //块的实际大小,最后一块是不确定的
		
		for(int i=0; i<num ;i++) {
			if(i == num-1) {
				actualBlockSize = this.length - beginPos;
			}
			splitWay(i,beginPos,actualBlockSize);
			beginPos += actualBlockSize;  //本次终点就是下个位置的起点
		}
		
	}
	
	
	/**
	 * 文件的分割
	 * @param i
	 * @param beginPos
	 * @param actualBlockSize
	 * @throws IOException 
	 */
	
	private void splitWay(int idnum, long beginPos, long actualBlockSize) throws IOException {


		//建立联系
		File src = new File(this.filePath);
		File dest = new File(this.blockName.get(idnum));
		
		//选择流
		RandomAccessFile raf = null;
		BufferedOutputStream bos = null;
		
		try {  //这里如果抛出异常,前面一系列调用都要抛出异常
			
			raf = new RandomAccessFile(src,"r");
			bos = new BufferedOutputStream(new FileOutputStream(dest));
			
			//读取文件
			try {
				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,len);
						break; //不然会读到超出部分
					}		
					
				}
			
				
			} catch (IOException e) {
				e.printStackTrace();
				System.out.println("文件读取失败");
			}
			
			
		} catch (FileNotFoundException e) {
			e.printStackTrace();
			System.out.println("文件找不到");
		}
		
			bos.close();
			raf.close();
	
	}
	
	
	/**
	 * 文件的合并
	 * @param args
	 * @throws IOException
	 */
	
	public void mergeFile(String destPath) throws IOException {
		//建立联系
		File dest = new File(destPath);
		
		//选择流
		BufferedInputStream bis = null;
		
		BufferedOutputStream bos = null;
		bos = new BufferedOutputStream(new FileOutputStream(dest,true));//文件的追加读取
		
		for(int i=0; i<this.blockName.size(); i++) {
			try {				
				bis = new BufferedInputStream(new FileInputStream(this.blockName.get(i)));
				
				//读取文件三板斧
				byte[] flush = new byte[1024];//缓冲区
				int len = 0;//接收长度
				
				while(-1 != (len=bis.read(flush))){//读取
					
					bos.write(flush, 0, len);
				}
				
				bos.flush();//强制刷出
				bis.close();
				
			} catch (FileNotFoundException e) {
				e.printStackTrace(); 
				System.out.println("文件没有找到");
			}finally {
				bos.close();
			}
		}
	}
	


	public static void main(String[] args) throws IOException {
	SplitFile file = new SplitFile("E:\\爱情公寓全集\\浙江.txt",25);	//以为长度大小分割
		
	System.out.println(file.num);
	//file.split("E:\\爱情公寓全集"); //先单独执行分割,再执行合并
	
	file.mergeFile("E:\\爱情公寓全集\\浙江2.txt");
	
	}
}


 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值