一.思路:
1.文件切割:
使用类RandomAccessFile ,其中方法seek可以自定义读取位置,读一段,通过字节输出流(我使用BufferedOutputStream)写一段
2.文件合并
读取多个文件写入一个文件,读取使用字节输入流(BufferedInputStream),输出使用字节输出流就可以(BufferedOutputStream)
我使用的流
RandomAccessFile raf=new RandomAccessFile (fSrc,"r"); BufferedOutputStream bos=new BufferedOutputStream(new FileOutputStream(new File(this.list.get(i)))); BufferedInputStream bis=new BufferedInputStream(new FileInputStream(new File(fileName))); BufferedOutputStream raf=new BufferedOutputStream(new FileOutputStream(new File("D://destdir//HugeCHM.rar"),true),1024);
二.代码:
1.文件切割代码
package com.ahd.util; 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; /*** * 文件切割 * @author Administrator * */ public class FileSplit { /*** * 定义,初始化参数 */ private File fSrc=null; //目标文件夹地址 private static File fDest=new File("D://destdir"); //默认是1024 切割后文件大小 private int blockSize; //切割块数 private int blockNumber; //源文件大小 private int size; //存储切割后文件名称 private List<String> list; /*** * 定义构造方法 */ private FileSplit() { super(); list=new ArrayList<String>(); } public FileSplit(File fSrc, File fDest) { this(fSrc,fDest,1024); } public FileSplit(File fSrc, int blockSize) { this(fSrc,fDest,blockSize); } public FileSplit(String strSrc, String destSrc) { this(strSrc,destSrc,1024); } public FileSplit(String strSrc, String destSrc,int blockSize) { this(new File(strSrc),new File(destSrc),blockSize); } public FileSplit(File fSrc, File fDest, int blockSize) { this(); this.fSrc = fSrc; this.fDest = fDest; this.blockSize = blockSize; init(); } /*** * 初始化 */ public void init(){ //增加健壮性 if(!fSrc.exists()||fSrc==null){ return; } if(this.blockSize>fSrc.length()){ this.blockSize=(int) fSrc.length(); } this.size=(int) fSrc.length(); this.blockNumber=(int) Math.ceil(size*1.0/blockSize); initList(); } /*** * 初始化List */ public void initList(){ String pathName=fSrc.getName(); for(int i=0;i<this.blockNumber;i++){ list.add(fDest.getAbsolutePath()+"/"+pathName+".part"+i); } } /*** * 分割split * @throws IOException */ public void split() throws IOException{ long beginPos=0; for(int i=0;i<this.blockNumber;i++){ splitDetail(i,beginPos,this.blockSize); } } //详细切割步骤 private void splitDetail(int i, long beginPos, int blockSize) throws IOException { //创建流 RandomAccessFile raf=new RandomAccessFile (fSrc,"r"); BufferedOutputStream bos=new BufferedOutputStream(new FileOutputStream(new File(this.list.get(i)))); //文件操作 byte []b=new byte[1024]; int len=0; raf.seek(beginPos); while(-1!=(len=raf.read(b))){ if(blockSize>len){ bos.write(b, 0, len); blockSize-=len; }else{ bos.write(b,0,blockSize); } bos.flush(); } //释放流 bos.close(); raf.close(); } }
2.文件合并主要代码(可以与切割代码放到一起使用)
public void fileMerge() throws IOException{ for(int i=0;i<blockNumber;i++){ MergeDetail(i,list.get(i)); } } private void MergeDetail(int i, String fileName) throws IOException { // TODO Auto-generated method stub //选择流 BufferedInputStream bis=new BufferedInputStream(new FileInputStream(new File(fileName))); BufferedOutputStream raf=new BufferedOutputStream(new FileOutputStream(new File("D://destdir//HugeCHM.rar"),true),1024); //文件操作 int len=0; byte []b=new byte[1024]; while(-1!=(len=bis.read(b))){ raf.write(b); } raf.close(); bis.close(); }