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面向对象练习
下一篇: Java面向对象 练习