面向对象思想——封装*分割
任务:分割个文件,保存到一个文件夹里,然后合并成一个文件
合并实质:将文件拷贝到目的文件中,并以追加append的形式输出
多个输入流,一个输出流
程序测试:
public class SplitFile {
private File src; // 源头
private String destDir; // 目的地(文件夹)
private List<String> destPaths; // 所有分割后的文件存储路径
private int blockLen;// 每块大小
private int num;// 块数:多少块
public SplitFile(String srcPath, String destDir, int blockLen) {
this.src = new File(srcPath);
this.destDir = destDir;
this.blockLen = blockLen;
this.destPaths = new ArrayList<>();
init();
}
// 初始化
private void init(){
// ②计算文件块数
long len = this.src.length();/*未分割的文件大小*/
/*块数 = 文件大小 / 块大小*/
this.num = (int)Math.ceil(len*1.0/blockLen);/*强制转型(int)-向上取整( ceiling天花板)-强制转型(double)*/
// 路径
for(int i = 0; i < this.num; i++) {
this.destPaths.add(this.destDir + "/" + i + "-" + this.src.getName());
}
}
// 分割
public void split() throws IOException {
long len = src.length();/*未分割的文件大小*/
// ①计算每一块的起始位置、大小
int beginPos = 0;/*设置变量保存可变的起始位置*/
int actualSize = (int)(blockLen>len?len:blockLen);/*设定当前文件块大小*/
for(int i = 0; i < num; i++ ) {
beginPos = i*blockLen;
if(i == num-1) {/*最后一块文件的大小 = 未分割的文件大小*/
actualSize = (int)len;
}else {/*不是最后一块,当前文件块大小= 块大小; 未分割的文件大小 = 未分割的文件大小 - 当前文件块大小*/
actualSize = blockLen;
len -= actualSize;
}
splitDetail(i,beginPos,actualSize);
}
}
// 把每个分割的文件块另存为一个文件
private void splitDetail(int i, int beginPos,int actualSize) throws IOException {
RandomAccessFile raf = new RandomAccessFile(this.src, "r");
RandomAccessFile raf2 = new RandomAccessFile(this.destPaths.get(i) , "rw");
// 随机读取
raf.seek(beginPos);
// 读取(因为是字节流,所以读取方式和之前分段读取的操作一样)
byte[] flush = new byte[10240];
int len = -1;
while(-1 != (len = raf.read(flush))) {
/*一次读取的大小<实际大小,则获取本次读取所有内容*/
if(actualSize > len) {
raf2.write(flush, 0, len);
actualSize -= len;/*实际大小减少*/
}else {/*一次读取的大小>实际大小,则只能要实际大小那么多的内容*/
raf2.write(flush, 0, actualSize);
break;/*跳出循环*/
}
}
raf2.close();
raf.close();/*需要释放*/
}
// 文件合并
public void merge(String destPath) throws IOException {
//输出流
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(destPath,true));
//输入流
BufferedInputStream bis = null;
byte[] flush = new byte[1024];
int len = -1;
for(int i = 0 ; i < num ; i++) {
bis = new BufferedInputStream(new FileInputStream(destPaths.get(i)));
//拷贝
while(-1 != (len = bis.read(flush))) {
bos.write(flush, 0, len);
}
bos.flush();
bis.close()
}
bos.close();
}
public static void main(String[] args) throws IOException {
SplitFile sf = new SplitFile("abc.txt","dest", 30);
sf.split();
sf.merge("cba.txt");
}
}
运行结果:
实验总结:
1.初始化时 this.num 少了 this 导致num的值一直为0,通过debug找到错误
2.仍有问题未解决,如果文件是图片的话,永远只有第一张显示稍微正常,后面的都无法显示