Java实现文件的分割与合并
程序员文章站
2022-03-07 12:23:24
本文实例为大家分享了java实现文件的分割与合并的具体代码,供大家参考,具体内容如下一、文件分割实现思想1、设置分割文件(块)的大小;2、通过输入流获取源文件的大小;3、根据1、2步的计算结果计算出分...
本文实例为大家分享了java实现文件的分割与合并的具体代码,供大家参考,具体内容如下
一、文件分割实现思想
1、设置分割文件(块)的大小;
2、通过输入流获取源文件的大小;
3、根据1、2步的计算结果计算出分割后的文件个数(源文件的大小 / 设置分割文件的大小 ,如果设置的文件大小大于源文件的大小,接下来判断1、2步计算结果,如果余数为0,则文件个数为商值,如果余数大于0,则文件个数为商值加1。
如果设置分割文件的大小小于源文件的大小,那么文件个数为1。);
4、分割文件(边读边写)。
二、文件合并实现思想
1、文件合并与文件分割实现思想的第4步类似,就是边读边写。
方式一:调用api中的randomaccessfile,此类的实例支持对随机存取文件的读取和写入。按块分割与合并,示例代码如下:
package com.cn.filesplite1; 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.inputstream; import java.io.randomaccessfile; import java.io.sequenceinputstream; import java.util.arraylist; import java.util.list; import java.util.vector; public class splitfile { //文件的路径 private string filepath; //文件名 private string filename; //文件大小 private long length; //块数 private int size; //每块的大小 private long blocksize; //分割后的存放目录 private string destblockpath; //每块的名称 private list<string> blockpath; public splitfile(){ blockpath = new arraylist<string>(); } public splitfile(string filepath,string destblockpath){ this(filepath,destblockpath,1024); } public splitfile(string filepath,string destblockpath,long blocksize){ this(); this.filepath= filepath; this.destblockpath =destblockpath; this.blocksize=blocksize; init(); } /** * 初始化操作 计算 块数、确定文件名 */ public void init(){ file src =null; //健壮性 if(null==filepath ||!(((src=new file(filepath)).exists()))){ return; } if(src.isdirectory()){ return ; } //文件名 this.filename =src.getname(); //计算块数 实际大小 与每块大小 this.length = src.length(); //修正 每块大小 if(this.blocksize>length){ this.blocksize =length; } //确定块数 size= (int)(math.ceil(length*1.0/this.blocksize)); //确定文件的路径 initpathname(); } private void initpathname(){ for(int i=0;i<size;i++){ this.blockpath.add(destblockpath+"/"+this.filename+".part"+i); } } /** * 文件的分割 * 0)、第几块 * 1、起始位置 * 2、实际大小 * @param destpath 分割文件存放目录 */ public void split(){ long beginpos =0; //起始点 long actualblocksize =blocksize; //实际大小 //计算所有块的大小、位置、索引 for(int i=0;i<size;i++){ if(i==size-1){ //最后一块 actualblocksize =this.length-beginpos; } spiltdetail(i,beginpos,actualblocksize); beginpos+=actualblocksize; //本次的终点,下一次的起点 } } /** * 文件的分割 输入 输出 * 文件拷贝 * @param idx 第几块 * @param beginpos 起始点 * @param actualblocksize 实际大小 */ private void spiltdetail(int idx,long beginpos,long actualblocksize){ //1、创建源 file src = new file(this.filepath); //源文件 file dest = new file(this.blockpath.get(idx)); //目标文件 //2、选择流 randomaccessfile raf = null; //输入流 bufferedoutputstream bos=null; //输出流 try { raf=new randomaccessfile(src,"r"); bos =new bufferedoutputstream(new fileoutputstream(dest)); //读取文件 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, (int)actualblocksize); break; } } } catch (filenotfoundexception e) { e.printstacktrace(); } catch (ioexception e) { e.printstacktrace(); }finally{ fileutil.close(bos,raf); } } /** * 文件的合并 */ public void merge(string destpath){ //创建源 file dest =new file(destpath); //选择流 bufferedoutputstream bos=null; //输出流 sequenceinputstream sis =null ;//输入流 //创建一个容器 vector<inputstream> vi = new vector<inputstream>(); try { for (int i = 0; i < this.blockpath.size(); i++) { vi.add(new bufferedinputstream(new fileinputstream(new file(this.blockpath.get(i))))); } bos =new bufferedoutputstream(new fileoutputstream(dest,true)); //追加 sis=new sequenceinputstream(vi.elements()); //缓冲区 byte[] flush = new byte[1024]; //接收长度 int len =0; while(-1!=(len=sis.read(flush))){ bos.write(flush, 0, len); } bos.flush(); fileutil.close(sis); } catch (exception e) { }finally{ fileutil.close(bos); } } /** * @param args */ public static void main(string[] args) { //1024 * 30 表示按照每块30kb大小分割 splitfile split = new splitfile("f:/123/1234/logfile.txt","f:/123/",1024 * 30); system.out.println(split.size); // split.split(); split.merge("f:/123/logfile.txt"); } }
package com.cn.filesplite1; import java.io.closeable; public class fileutil { /** * 工具类关闭流 * 可变参数: ... 只能形参最后一个位置,处理方式与数组一致 */ public static void close(closeable ... io){ for(closeable temp:io){ try { if (null != temp) { temp.close(); } } catch (exception e) { } } } /** * 使用泛型方法 */ public static <t extends closeable> void closeall(t ... io){ for(closeable temp:io){ try { if (null != temp) { temp.close(); } } catch (exception e) { } } } }
方式二:用读写的方式实现文件的分割与合并,具体实现如下代码所示:
定义一个抽象类
package com.cn.filesplite2; import java.io.file; import java.io.ioexception; /** * 文件分割 * @author administrator * */ public abstract class splitfile { /** * 设置单个文件的大小 * 根据自己需求设置大小,字节进率为1024,本例中设置的最大分割文件大小是2gb。 */ public static long max_byte = 1024 * 1024 * 1024 * 2l; //2g /** * 获取可以分割的文件数 * @param filebyte 文件大小 * @param fileparh 文件路径 * @return */ public abstract int getsplitfilenum(long filebyte,string fileparh); /** * 获取文件长度 * @param file * @return * @throws ioexception */ public abstract long getfilelength(file file) ; /** * 分割文件 * @param srcfile * @param splitfilenum * @return * @throws ioexception */ public abstract string[] splitfile (file srcfile,int splitfilenum) throws ioexception; /** * 合并文件 * @param files * @param newfile * @throws ioexception */ public abstract void mergefile(string[] files,string newfile) throws ioexception; }
实现类
package com.cn.filesplite2; import java.io.bufferedreader; import java.io.bufferedwriter; import java.io.file; import java.io.filereader; import java.io.filewriter; import java.io.ioexception; /** * 文本文件分割 * @author administrator * */ public class splittextfile extends splitfile{ @override public long getfilelength(file file) { filereader fr = null; bufferedreader br = null; //文件大小 long filesize = 0; try { fr = new filereader(file); br = new bufferedreader(fr); string line = br.readline(); //按行读取文件 while(line != null){ //计算文件大小 filesize += line.length(); line = br.readline(); } } catch (ioexception e) { e.printstacktrace(); }finally{ //关闭输入流 try { if(br != null){ br.close(); } if(fr != null){ fr.close(); } } catch (ioexception e) { e.printstacktrace(); } } //返回文件大小 return filesize; } @override public int getsplitfilenum(long filebyte,string fileparh){ filebyte = getfilelength(new file(fileparh)); if(max_byte < filebyte){ if(filebyte % max_byte == 0){ return (int) (filebyte/max_byte); }else{ return (int) (filebyte/max_byte) + 1; } } return 1; } @override public string[] splitfile(file srcfile, int splitfilenum) throws ioexception { splitfilenum = getsplitfilenum(getfilelength(srcfile), srcfile.tostring()); if(splitfilenum <= 0){ return null; } filereader fr = null; bufferedreader br = null; long readnum = 0; string[] splits = new string[splitfilenum]; try { fr = new filereader(srcfile); br = new bufferedreader(fr); int i = 0; while(splitfilenum > i){ //分割后的文件名 string name = null; //文件后缀 string namelast = null; if(srcfile.getname().indexof(".") != -1){ name = srcfile.getname().substring(0, srcfile.getname().indexof(".")); int last = srcfile.getname().lastindexof("."); // system.out.println(i); // string string = str.substring(i); namelast = srcfile.getname().substring(last); }else{ name = srcfile.getname(); } splits[i] = srcfile.getparent() + "/" + name + "_" + i + namelast; file wfile = new file(splits[i]); if(!wfile.exists()){ wfile.getparentfile().mkdirs(); wfile.createnewfile(); } filewriter fw = new filewriter(wfile,false); bufferedwriter bw = new bufferedwriter(fw); string line = br.readline(); int flush = 0; while(line != null){ if(line.trim().length() == 0){ line = br.readline(); continue; } readnum += line.length(); if(i + 1 == splitfilenum){ bw.write(line); bw.newline(); }else{ if(readnum >= max_byte){ bw.write(line); bw.newline(); break; }else{ bw.write(line); bw.newline(); } } line = br.readline(); if(flush % 100 == 0){ bw.flush(); } } bw.flush(); fw.flush(); bw.close(); fw.close(); readnum = 0; i++; } } catch (runtimeexception e) { e.printstacktrace(); } finally{ try { if(br != null) br.close(); if(fr != null) fr.close(); } catch (exception e) { e.printstacktrace(); }finally{ br = null; fr = null; } } return splits; } @override public void mergefile(string[] files, string newfile) throws ioexception { file wfile = new file(newfile); filewriter writer = null; bufferedwriter bufferedwriter = null; try { writer = new filewriter(wfile,false); bufferedwriter = new bufferedwriter(writer); for(int i = 0; i < files.length; i++){ file rfile = new file(files[i]); filereader reader = new filereader(rfile); bufferedreader bufferedreader = new bufferedreader(reader); string line = bufferedreader.readline(); while(line != null){ if(line.trim().length() == 0){ line = bufferedreader.readline(); continue; } bufferedwriter.write(line); bufferedwriter.newline(); line = bufferedreader.readline(); } } bufferedwriter.flush(); writer.flush(); } catch (exception e) { e.printstacktrace(); }finally{ if(bufferedwriter != null) bufferedwriter.close(); bufferedwriter = null; if(writer != null) writer.close(); writer = null; } } }
测试类
package com.cn.filesplite2; import java.io.file; import java.io.ioexception; import org.junit.test; public class testsplitfile { splittextfile splittextfile = new splittextfile(); @test public void funsplitfile() throws ioexception{ string srcpath = "e:/splitfile/splitfile.txt"; file file = new file(srcpath); long filelength = splittextfile.getfilelength(file); system.out.println("文件大小:" + filelength); int partitionfilenum = splittextfile.getsplitfilenum(filelength, srcpath); system.out.println("个数" + partitionfilenum); //文件分割 splittextfile.splitfile(new file(srcpath), partitionfilenum); } @test public void funmergefile() throws ioexception{ string[] files = {"e:/splitfile/splitfile0", "e:/splitfile/splitfile1", "e:/splitfile/splitfile2" // ...files/ }; string newfile = "e:/splitfile/newmergefile"; splittextfile.mergefile(files, newfile); } }
以上内容如有任何问题或错误,恳请大家能给予意见,我会及时更正,谢谢大家。
本文的全部内容介绍完了,希望对大家的学习有所帮助,也希望大家多多支持。
上一篇: Android ActivityManager使用案例详解
下一篇: SQL注入详解(扫盲篇)