文件切割合并程序学习笔记

来源:互联网 发布:大势至软件 编辑:程序博客网 时间:2024/05/16 18:12

    import java.io.File;      import java.io.IOException;      import org.junit.Test;            public class MainClass {          /**          * 需求:1>.将一个大文件按大小切割成多个小文件,分割后,删除原文件  2>.将多个被切割后的碎片文件合并成一个文件,合并后删除原来的碎片文件          * 思路分析:          * 一、切割文件          * 1.>根据文件路径和文件名获取到该文件          * 2.>切割文件就是将一个文件通过输出流写入到多个文件中,所以要用到一个文件输入流:FileInputStream进行读入内存的操作和          *    多个文件输出流:FileOutputStream类进行写的操作          * 3.>定义缓冲区,进行读取,每读满一个碎片文件进行一次文件流的关闭,关闭后继续写下一个文件          * 4.>碎片文件的名称按照数字命名,第一个文件命名为1.part,第二个命名为2.part          * 5.>将文件名称和文件的个数写入到一个properties文件中去方便下次合并操作          *           * 二、合并文件          * 1.>根据指定的碎片文件的目录,读取properties配置文件          * 2.>根据properties配置文件,获取碎片文件的数量          * 3.>获取所有碎片文件,并添加到List集合中          * 4.>将List集合利用集合工具类Collections中的方法enumeration将集合中的多个流转化为序列流          * 5.>将序列流中的数据写入到指定的文件中去,写完后删掉所有碎片文件          *           * 三、说明          *     本程序支持大文件切割          *     如果正使用的话,还需要测试多线程切割和合并          *     第二个是异常的处理,这个要根据具体需要来处理了          */                    //测试:将E:\split下的1.JPG进行切割          @Test          public void fileSplit(){              //需要切割的文件              File file = new File("E:\\CrossFire_OBV212_Full.exe");              //切割后的路径              File splitedDir = new File("E:\\split");              SplitFile.fileSplit(file,splitedDir);          }                    //测试:将E:\split下多个碎片文件进行合并,合并后文件存储到指定目录下          @Test          public void fileMerge() {              //要合并的的碎片文件的目录              File file = new File("E:\\split");              //合并后文件存放的目录              File fileMerged = new File("E:\\merge");              try {                  MergeFile.fileMerge(file, fileMerged);              } catch (IOException e) {                  e.printStackTrace();              }          }            }      import java.io.File;      import java.io.FileInputStream;      import java.io.FileNotFoundException;      import java.io.FileOutputStream;      import java.io.IOException;      import java.util.Properties;            public class SplitFile {                //缓冲区:1M          private static final int BUFFERED_SIZE = 1048576;          //设定每个文件碎片的大小,根据大小来分割文件,每个文件100M          private static final int FILE_SIZE = 104857600;                    /**          * 文件切割          * @param file 要切割的文件          * @param splitDir 切割后的文件路径          * */          public static void fileSplit(File file,File splitedDir) {              try {                  FileInputStream fis = new FileInputStream(file);                  FileOutputStream fos = null;                  byte[] buf = new byte[BUFFERED_SIZE];                  int len = 0;                  int count = 0;                  int filesize = 0;                  while((len=fis.read(buf))!=-1){                      if(filesize>=FILE_SIZE){                          //关闭上一个文件的输出流                          fos.close();                          //置空上一个文件碎片,准备重新创建新的碎片文件                          fos = null;                          //重新计算已经写入新的碎片文件的数据大小                          filesize = 0;                      }                      if(fos==null)                          fos = new FileOutputStream(new File(splitedDir,(++count)+".part"));                      filesize += len;                      fos.write(buf, 0, len);                      fos.flush();                  }                  //关闭最后一个写入的碎片文件的流                  if(fos != null){                      fos.close();                  }                  fis.close();                  writeConfig(splitedDir,file,count);                  clearSourceFile(file);              } catch (FileNotFoundException e) {                  e.printStackTrace();              } catch(IOException ie){                  ie.printStackTrace();              }          }                    //删除被切割的文件          private static void clearSourceFile(File file) {              file.delete();          }                      /**          * @param splitedDir 文件被切割后的存放路径          * @param file 被切割的文件          * @param count 文件个数          * @throws IOException           * */          public static void writeConfig(File splitedDir, File file, int count) throws IOException {              //1.创建properties配置文件              File propfile = new File(splitedDir,(count+1)+".properties");              FileOutputStream  fos = new FileOutputStream(propfile);              //2.用Properties类创建对象,将信息写入到内存中              Properties prop = new Properties();              prop.setProperty("filename", file.getName());              prop.setProperty("count", count+"");              //3.将Properties对象store进配置文件              prop.store(fos, "Created By Le.Zhou");          }      }      import java.io.File;      import java.io.FileInputStream;      import java.io.FileNotFoundException;      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.List;      import java.util.Properties;            public class MergeFile {                //定义配置文件后缀名          private static final String PROPERTIES_SUFFIX = ".properties";          //定义碎片文件后缀名          private static final String PART_SUFFIX = ".part";          //取缓冲区:1M          private static final int BUFFERED_SIZE = 1048576;                    /**          * 根据文件路径读取properties配置文件,并合并指定路径下的文件          * @param filepath 要合并的的碎片文件的目录          * @param fileMerged 碎片文件合并后文件的存放目录          * @throws IOException           * */          public static void fileMerge(File filepath, File fileMerged) throws IOException {              //检测碎片文件目录是否正确              if(filepath==null || !filepath.isDirectory()){                  throw new RuntimeException("提供的碎片文件目录不是一个目录!");              }                            //检测碎片文件合并后的存放目录是否正确              if(!fileMerged.isDirectory()){                  boolean flag = fileMerged.mkdirs();                  if(!flag)                      throw new RuntimeException("创建文件存放路径失败,请提供正确的文件存放路径!");              }                            //获取properties配置文件              File[] propFiles = getFilesBySuffix(filepath, PROPERTIES_SUFFIX);              if(propFiles.length != 1){                  throw new RuntimeException(filepath.getPath()+"下,后缀为.properties的文件不存在或数量不唯一");              }              Properties prop = getPropObject(propFiles[0]);              //从配置文件中读取碎片文件数量              String count = prop.getProperty("count");              String fileName = prop.getProperty("filename");              if(count==null){                  throw new RuntimeException("配置文件中的信息有误:count属性对应的值为空");              }                            //获取被分割的文件碎片              File[] partFiles = getFilesBySuffix(filepath,PART_SUFFIX);                            List<FileInputStream> flist = new ArrayList<FileInputStream>();              if(Integer.parseInt(count) != partFiles.length)                  throw new RuntimeException("配置文件中的count属性的值与实际part文件数量不相符");                            //将文件碎片添加到一个集合中              for(File f : partFiles){                  flist.add(new FileInputStream(f));              }                            //将文件集合转化为序列流              SequenceInputStream sis = fileList2SeqInputStream(flist);                            //合并文件              write2Disk(sis, fileMerged, fileName);                            //关闭序列流              sis.close();                            //清除碎片文件              clearDebrisFiles(filepath);          }                    //清除碎片文件          private static void clearDebrisFiles(File filepath) {              File[] file = filepath.listFiles();              for(File f : file){                  boolean flag = f.delete();                  if(!flag)                      throw new RuntimeException(filepath.getPath()+"下,"+f.getName()+"删除失败!");              }          }                //将文件集合转化为序列流          private static SequenceInputStream fileList2SeqInputStream(                  List<FileInputStream> flist) {              Enumeration<FileInputStream> enumList = Collections.enumeration(flist);              SequenceInputStream sis = new SequenceInputStream(enumList);              return sis;          }                    //根据文件后缀获取文件          private static File[] getFilesBySuffix(File filepath, String suffix) {              File[] propFiles = filepath.listFiles(new FilterBySuffix(suffix));              return propFiles;          }                    //获取碎片文件数量          private static Properties getPropObject(File propFiles) throws IOException,                  FileNotFoundException {              FileInputStream fis = new FileInputStream(propFiles);              //获取properties配置文件中的信息              Properties prop = new Properties();              prop.load(fis);              fis.close();              return prop;          }                    //合并文件          private static void write2Disk(SequenceInputStream sis, File fileMerged, String filename) throws IOException {              FileOutputStream out = new FileOutputStream(new File(fileMerged, filename));              byte[] buf = new byte[BUFFERED_SIZE];              int len = 0;              while((len=sis.read(buf))!=-1){                  out.write(buf, 0, len);              }              out.close();          }                }      import java.io.File;      import java.io.FilenameFilter;            /**      * 文件后缀名过滤器      * */      public class FilterBySuffix implements FilenameFilter {                //后缀名          private String suffix;                    public FilterBySuffix(String suffix){              this.suffix = suffix;          }                    public boolean accept(File dir, String name) {              return name.endsWith(suffix);          }            }  


原创粉丝点击