利用IO流对文件进行分割和无损还原合并

来源:互联网 发布:漱口水 酒精 知乎 编辑:程序博客网 时间:2024/05/16 19:07
1、实现原理分布写在注释里,基本思路是将源文件分割为若干份,之后再将分割的文件进行合并还原。

2、实现代码如下:


package com.tiger.copy.split.combine;import java.io.*;/** * 文件的分割与合并 * @author tiger * @Date 2017年7月21日 */public class FileSplitAndCombine {/* * 测试 */public static void main( String[] args ) throws IOException {String cPath = "E:\\tigerFolder\\J2SE6.0 API(冷冬大雪).chm";String sPath = "E:\\tigerFolder\\split";fileSplit(cPath,sPath,9,1024,"chm");/*================================================================*///String srcPath = "E:\\tigerFolder\\split";//String destPath = "E:\\tigerFolder\\combine.chm";//fileCombine(srcPath,destPath,9,1024,".chm");}/** * 文件的切割 * @param srcPath 切割源文件路径 * @param destPath 合并文件路径 * @param size 切割块数 * @param speed 切割速度 * @param suffix 切割文件后缀 * @throws IOException 异常处理 */public static void fileSplit(String srcPath,String destPath,int size,int speed,String suffix) throws IOException{long start = System.currentTimeMillis();InputStream is = new FileInputStream( srcPath );//获取文件可读取的字节数,依据这个对文件进行分割int total = is.available();//文件分块切割数目 size,余数放到最后一个文件中。int[] blocks = new int[size];for (int i = 0; i < size; i++) {if (i == size - 1) {blocks[i] = total/size + total%size;}else {blocks[i] = total/size;}}//定义创建 size 个输出流的数组.OutputStream[] outs = new OutputStream[ size ];for (int i = 0; i < outs.length; i++) {outs[i] = new FileOutputStream( destPath + i + suffix);}int index = 0; //表示要读取到哪一块,一块一块地读取int remain = blocks[ index ];//记录当次需要读取多少个字节int needRead;   int len = 0;byte[] buff = new byte[speed];while( index < size ){//处理数组越界问题if( remain > speed ){needRead = speed;}else{needRead = remain;}//读取数据len = is.read( buff, 0, needRead );if( len != -1 ){   //写出数据、读多少, 写多少outs[index].write( buff, 0, len );//强制刷新数据outs[index].flush();//读多少减多少remain = remain - len; //索引指向下一个文件块if( remain == 0 ){index ++; if( index < size ){remain = blocks[index];}}}}is.close();long end = System.currentTimeMillis();System.out.println("执行文件切割耗时: "+(end - start)/1000 + " s");System.out.println( "程序结束 ..." );}/** * 文件的合并 * @param srcPath 分散文件源文件路径 * @param destPath 合并成功后文件的存放路径 * @param size 源文件数目 * @param speed 合并速度 * @param suffix 合并文件后缀 * @throws IOException 异常处理 */public static void fileCombine(String srcPath,String destPath,int size,int speed,String suffix) throws IOException{long start = System.currentTimeMillis();//目标输出流OutputStream os = new FileOutputStream(destPath,true);//输出的追加的后边//定义创建 4 个输入流的数组.InputStream[] is = new InputStream[size];for (int i = 0; i < size; i++) {is[i] = new FileInputStream(srcPath + i + suffix);}//获取每个文件大小int[] blocks = new int[size];for (int i = 0; i < size; i++) {blocks[i] = is[i].available();}int needRead;//一次int index = 0;//文件号索引int remain = blocks[index];//记录读取到哪个文件byte[] buff = new byte[speed];//缓冲,每次读取的大小int len = 0;//接收数据while (index < size) {if( remain > speed ){needRead = speed;}else{needRead = remain;  //剩余数 ...}//读一次,写一次len = is[index].read(buff, 0, needRead);//如果字节够,则将byte数组中的数据读完,否则读剩下的。if (len != -1) {//边读取边输出到本地文件中,读多少,输出多少os.write(buff, 0, len);//off  需要一个标签来记录,将文件输入到指定文件中。//读多少,减多少,直到文件大小被减为0 ,则表明文件被读取完毕,接着判断读取下一个文件remain = remain - len;}if( remain == 0 ){//表明文件被读取完毕,接着判断读取下一个文件//记录文件号index ++; if( index < size ){remain = blocks[index];}}}os.close();long end = System.currentTimeMillis();System.out.println("执行文件合并耗时: "+(end - start)/1000 + " s");System.out.println( "程序结束 ..." );}}
原创粉丝点击