文件的切割与合并

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Properties;
/*
* 切割文件
* 一个源文件,切割成多个目的文件
* (一个输入流,多个输出流)
*/

public class splitFileDemo {
private static final int SIZE = 1024*1024;
public static void main(String[] args) throws IOException {
    File dir = new File("6.mp3");
    splitFile_2(dir);
}
private static void splitFile_2(File dir) throws IOException {
    //1,建立一个字节读取流对象关联要被切割的文件
    FileInputStream fis = new FileInputStream(dir);
    //2,建立一个缓冲区,用来存放指定大小的文件,进行切割。这里是1M大小
    byte[] buff = new byte[SIZE];
    //3,建立一个文件夹,用来存放切割后文件。如果不存在就自己创建
    File file = new File("C:\\splitFile");
    if(!file.exists()){
        file.mkdirs();//创建多层文件夹
    }
    int len = 0;
    int count = 0;
    FileOutputStream fos = null;
    while((len = fis.read(buff))!=-1){
        count++;
        /*每1M该文件大小就存放一份,因为重名会被覆盖
         *所以定义一个变量count,使每次存放到硬盘的文件不被覆盖
         */
         fos = new FileOutputStream(new File(file,count+".part"));
         fos.write(buff,0,len);
         //每写入一个碎片文件记得关闭流
         fos.close();
    }
    /*
     * 4,因为要记录切割文件的文件名,和文件个数,为了将其保存起来,方便合并
     * 用properties集合,然后将其存储到文件中
     */
    Properties pro = new Properties();
    //将要被切割的文件名存放到集合中
    pro.setProperty("filename", dir.getName());
    //将碎片文件个数信息存放到集合中,因为包含信息本身文件 ,所以count+1。
    //Property集合存放的是字符串信息,所以要将整数转换为字符串
    pro.setProperty("partcount", Integer.toString(count+1));
    //定义一个输出流,用来将信息数据写到文件中
    fos = new FileOutputStream(new File(file,".properties")); 
    //将信息保存到文件中
    pro.store(fos , "info");
    //关闭流
    fos.close();
    fis.close();        
}}

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.SequenceInputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.Properties;
/*
* 合并文件
* 多个输入流一个输出流
*
*/

public class MergeFileDemo2 {
private static final int SIZE = 1024*1024;

public static void main(String[] args) throws IOException {
    //建立需要合并的文件对象
    File dir = new File("c:\\splitFile");
    mergeFile_2(dir);
}

public static void mergeFile_2(File dir) throws IOException {
    //1,获取所要合并文件的信息
    ===========================================================
    //我们需要获取所要合并的文件信息,
    如文件的个数,所切割的文件名。那就用到过滤
    File[] files = dir.listFiles(new FileBySuffix(".properties"));
files里有且只有一个该信息文件,如果多了或没有,抛异常
    if(files.length!=1){
        throw new RuntimeException("你要合并的文件信息不符合标准");
    }
    //成功获得信息就进行下一步,获取信息内容
    Properties pro = new Properties();
    //载入文件
    pro.load(new FileInputStream(files[0]));
    int count =Integer.parseInt(pro.getProperty("partcount"));
    //同样要做健壮性判断,过滤剩下part文件,也就是碎片文件
    File[] partfile = dir.listFiles(new FileBySuffix(".part"));
    if(partfile.length!=count-1){
        throw new RuntimeException("碎片文件个数不对");
    }

    for(int i = 0;i<partfile.length;i++){
        al.add(new FileInputStream(partfile[i]));
    }
    */
    //2,将碎片文件与流相关联,将流存储到集合中,以便合并。
    ==============================================================
    ArrayList<FileInputStream> al = new ArrayList<FileInputStream>();
    for(int i = 1;i<count;i++){
        al.add(new FileInputStream(new File(dir,i+".part")));
    }
    //枚举该集合的的元素,用于序列流的传入参数
    Enumeration<FileInputStream> en = Collections.enumeration(al);
    //3,合并过程
    ==============================================================
    //序列流 用于合并几个输入流,然后用一个输出流输出到文件中
    SequenceInputStream sis = new SequenceInputStream(en);
    //获取切割前的文件名,作为合并后的文件名。
    String name = pro.getProperty("filename");
    //建立一个输出流对象,用于输出到相应的文件中
    FileOutputStream fos = new FileOutputStream(new File(dir,name));
    byte [] buff =new byte[SIZE];
    int len = 0;
    while((len=sis.read(buff))!=-1){
        fos.write(buff,0,len);
        fos.flush();
    }
    //关闭流
    fos.close();
    sis.close();
}}

//过滤器
import java.io.File;
import java.io.FilenameFilter;
public class FileBySuffix implements FilenameFilter {

private String suffix;

public FileBySuffix(String suffix) {
    super();
    this.suffix = suffix;
}

public boolean accept(File dir, String name) {

    return name.endsWith(suffix);
}}
posted @ 2016-11-07 18:14  第五个世界  阅读(153)  评论(0编辑  收藏  举报