欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

java IO流_文件分割_初始化各项参数_练习2

程序员文章站 2022-04-03 17:14:54
...

package IO流_165_166_文件分割与合并_初始化各项参数;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.ArrayList;
import java.util.List;

import IO流_164_文件分割与合并_RandomAccessFile.CloseUtil;

/**

  • 初始化各项参数及文件的分割思路
  • 1.分割的块数 size
  • 2.每一块的大小 blockSize;最后一块的文件大小=总文件的大小-(n-1)* blockSize
  • 3.每一块的名称
  • 4.分割
  •  1)第几块开始分割,每一块的起始点,文件实际大小 
    
  •  2)文件分割 
    

*/
public class SplitFile {//SplitFile文件分割

private String filePath; //文件的路径

private String fileName;//文件名

private long length;//文件大小

private int size;//块数

private long blockSize; //每块的大小 

private List<String> blockPath;	//每块的名称  并进行存储好;这样就不用每次重新存储

private RandomAccessFile bos;

private Object raf;

/*
 * 构造器相互调用
 */
//无参构造器
public SplitFile() {
	 blockPath =new ArrayList<String>();//创建目的地对象
}
//有参
public SplitFile(String filePath) {
	//blockSize = 1024;//定义每块的大小
	//this.filePath = filePath
    this(filePath,1024);//调用SplitFile(String filePath, long blockSize)
   
}
//有参
//文件路径和实际大小
public SplitFile(String filePath, long blockSize) {
	this();//调用SplitFile()
	this.filePath = filePath; 
	this.blockSize = blockSize;
	init();//调用
} 

/**
 *  参数初始化;计算块数,确定文件名	    
 * @param destPath 
 */
public void init(){ 
	//判断文件是否为空或者文件是否存在
	File src = null;
	//程序的健壮性;注意==号;
	if(null== filePath||!((src = new File(filePath)).exists())){//exists存在
		 return;
	} 
	//判断是否是一个文件夹
	if(src.isDirectory()){//isDirectory判断是否为文件夹
		return;
	}
	//文件名
	this.fileName = src.getName();
	
	//计算块数:实际大小与每块大小;先拿出实际大小
	this.length = src.length();//实际大小
	//判断后修正大小
	if(this.blockSize>length){//如果理论大小>实际大小
		this.blockSize = length;//则=实际大小
	}
	//确定块数 ;length/this.blockSize两个整数相除有可能余数为0;所以从乘以1.0;并强制double浮点类型转int
	size = (int)( Math.ceil(length*1.0/this.blockSize));//Math.ceil>=取最小整数,向上取值
	
} 
//确定每块的名称  创建方法;内部方法
private void initPathName(String destPath){//initPathName初始化路径名
	for(int i=0;i<size;i++){ 
		this.blockPath.add(destPath+"/"+this.fileName+".part "+i);//part部分;'.part'原来名称一部分
	}
} 
/**
 * 文件的分割思路 
 * 	1.第几块
 * 	2.起始位置
 * 	3.实际大小
 * 
 * @param destPath;分割文件存放目录
 * @throws IOException 
 */
public void split(String destPath) throws IOException{//split分割
	//确定文件路径
	initPathName(destPath);
	
	long beginPos = 0;//beginPos开始位置;
	long actualBlockSize =blockSize;//actualBlockSize实际的块大小;blockSize块的大小
	
	
	//计算所有块的大小,位置,块的索引
	for(int i=0;i<size;i++){
		 if(i==size-1){//最后一块;即不够除的部分
			 actualBlockSize = this.length-beginPos;//最后一块=文件长度- beginPos(最后一小块之前的位置)
		 }
		 spiltDetail(i,beginPos,actualBlockSize);
		 beginPos+=actualBlockSize;//本次终点就是下一次的起点
	 }
}
/**
 *	文件的分割;输入,输出;即文件的拷贝
 * 	spiltDetail分割的细节
 * 	idx第几块;beginpos从什么位置开始;actualBlockSize 实际块大小,因为最后一块不一定是设定字节的整数倍
 * @throws IOException 
 */
//@SuppressWarnings("resource")//抑制警告资源
private void spiltDetail(int idx,long beginPos,long actualBlockSize) throws IOException{
	//创建源
	File src = new File(this.filePath);//文件路径;源文件
	//目的地
	File dest = new File(this.blockPath.get(idx)); //目标文件
	//选择流
	RandomAccessFile raf = null;//输入流
	BufferedOutputStream bos = null;//输出流---
	raf = new RandomAccessFile(src,"r");//只读模式
	bos = new BufferedOutputStream(
			new FileOutputStream(dest));
	//读取文件;1.先定位
	raf.seek(beginPos);
	//2.缓冲区
	byte[] flush = new byte[1024];
	//接收长度
	int len = 0;
	try {
		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;
			}
			
		}
	} catch (IOException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}finally{
		CloseUtil.closeIO(bos, raf); 
	}
}

/**   
 * @param args 
 * @throws IOException 
 */ 
public static void main(String[] args) throws IOException {
	SplitFile file = new SplitFile("E:/xp/test/char.txt",1);//按一个字节
	System.out.println("按一个字节分多少块:"+file.size);
	SplitFile file1 = new SplitFile("E:/xp/test/char.txt",10);//按10个字节
	System.out.println("按10个字节分多少块:"+file1.size);
	SplitFile split = new  SplitFile("E:/xp/test/char.txt",10);//分割出文件并拷贝
	System.out.println(split.size);
	split.split("E:/xp/test");	
}

}
//结果-------------------------------------------------
java IO流_文件分割_初始化各项参数_练习2
分割并拷贝
java IO流_文件分割_初始化各项参数_练习2