本文实例为大家分享了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);
  
 }
}

以上内容如有任何问题或错误,恳请大家能给予意见,我会及时更正,谢谢大家。

本文的全部内容介绍完了,希望对大家的学习有所帮助,也希望大家多多支持www.887551.com。