java IO流_167_文件合并另一种方法SequenceInputStream_练习4

package IO流_167_文件分割与合并_文件合并;

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.Enumeration;
import java.util.List;
import java.util.Vector;
/**

  • SequenceInputStream 类 ;

  • SequenceInputStream 表示其他输入流的逻辑串联。它从输入流的有序集合开始,并从第一个输入流开始读取,

  •  直到到达文件末尾,接着从第二个输入流读取,依次类推,直到到达包含的最后一个输入流的文件末尾为止。 
    

    即先把很多流先组成一个流加在中间,然后在写出去

  • 面向对象编程;
    */
    public class SplitFile2 {
    private String filePath;//文件路径
    private int size;//块数
    private long blockSize;//每块大小
    private List blockPath;//每块存储的名称
    private String fileName;//每块名称
    private long length;//文件大小

    private String destBlockPath;//分割后的存放目录
    //构造器
    public SplitFile2() {
    blockPath = new ArrayList();
    }
    public SplitFile2(String filePath,String destBlockPath) {//构造器相互调用
    //this(filePath,1024,destBlockPath);//调用SplitFile(String filePath, long blockSize)
    //其他文件名的分割与合并; 调整下位置
    this(filePath,destBlockPath,1024);
    }
    /public SplitFile(String filePath, long blockSize,String destBlockPath) {
    this(); //调用 SplitFile()
    this.filePath = filePath;
    this.blockSize = blockSize;
    this.destBlockPath = destBlockPath;
    init();//调用
    }
    /
    //其他文件名的分割与合并; 调整下位置
    public SplitFile2(String filePath,String destBlockPath, long blockSize) {
    this(); //调用 SplitFile()
    this.filePath = filePath;
    this.blockSize = blockSize;
    this.destBlockPath = destBlockPath;
    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大小>实际的大小;则改成实际大小
    this.blockSize=length;
    }
    //确定块数;相同整数相除有可能变为0;所有乘1.0;
    size = (int) (Math.ceil(length1.0/this.blockSize)); //强转型
    initPathName();//确定文件路径
    }
    //获取每块的名称
    private void initPathName(){
    for(int i=0;i<size;i++){
    this.blockPath.add(destBlockPath+"/"+this.fileName+".part"+i);
    }
    }
    /

    • 分割后文件存放的目录

    • 1.第几块

    • 2.起始位置

    • 3.实际大小
      */
      public void split(){

      long beginPos = 0;//起始点为0;
      long actualBlockSize = blockSize;//actualBlockSize实际大小=原来的blockSize
      //计算所有块的大小,位置,索引
      for(int i=0;i<size;i++){
      //判断
      if(i==size-1){//最后一块
      actualBlockSize = this.length-beginPos;
      }
      splitDetail(i,beginPos,actualBlockSize);
      beginPos +=actualBlockSize;//本一次终点也是下一次起点
      }
      }
      /**

    • 文件分割 ;输入,输出,文件拷贝

    • @param idx;第几块

    • @param beginPos;起始点

    • @param actualBlockSize;实际大小
      */

    private void splitDetail(int idx,long beginPos,long actualBlockSize){
    File src = new File(this.filePath);//创建源
    File dest = new File(this.blockPath.get(idx));//目的地
    RandomAccessFile raf = null; //输入流
    BufferedOutputStream bos = null;//输出流文件的拷贝
    try {
    raf = new RandomAccessFile(src,“r”);//只读模式’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;//结束循环
    }
    }
    //注意这个不能忘 否则分割后的文件内容为空******************
    bos.flush();//强制刷出
    } catch (FileNotFoundException e) {
    e.printStackTrace();
    } catch (IOException e) {
    e.printStackTrace();
    }finally{
    CloseUtil.closeIO(bos, raf);
    }
    }
    /**

    • 文件的合并
    • @param destPath
      /
      /public void merge(String destPath){
      // 创建源
      File dest = new File(destPath);
      //选择流
      BufferedOutputStream bos = null;//输出流
      try {
      bos = new BufferedOutputStream(new FileOutputStream(dest,true));//true是追加;false是覆盖
      BufferedInputStream bis = null;//输入流
      for(int i=0;i<this.blockPath.size();i++){//blockPath每块存储的名称
      bis = new BufferedInputStream(new FileInputStream( new File(this.blockPath.get(i))));//处理异常
      //缓冲区
      byte[] flush = new byte[1024];
      //接收长度
      int len =0;
      while(-1!=(len= bis.read(flush))){//处理异常
      //查看内容是否写出
      System.out.println(new String(flush, 0, len));
      bos.write(flush, 0, len);
      }
      bos.flush();
      CloseUtil.closeIO(bis);
      }
      } catch (FileNotFoundException e) {
      e.printStackTrace();
      } catch (IOException e) {
      e.printStackTrace();
      }finally{
      CloseUtil.closeIO(bos);
      }
      }
      /
      /
      *
    • 另一种方法;文件的合并
    • @param destPath
      /
      public void merge2(String destPath){
      // 创建源
      File dest = new File(destPath);
      //选择流 ;BufferedOutputStream缓冲输出流; SequenceInputStream顺序输入流,序列流;
      BufferedOutputStream bos = null;//输出流
      SequenceInputStream sis = null;//输入流
      //创建一个容器;Vector类, 可以实现可增长的对象数组
      Vector vi = new Vector();
      try {
      for(int i=0;i<this.blockPath.size();i++){//blockPath每块存储的名称
      vi.add(new BufferedInputStream(new FileInputStream( new File(this.blockPath.get(i)))));
      }
      bos = new BufferedOutputStream(new FileOutputStream(dest,true));//true是追加;false是覆盖
      //elements元素
      sis = new SequenceInputStream(vi.elements( ));//处理异常
      //缓冲区
      byte[] flush = new byte[1024];
      //接收长度
      int len =0;
      while(-1!=(len= sis.read(flush))){//处理异常
      //查看内容是否写出
      System.out.println(new String(flush, 0, len)) ;
      bos.write(flush, 0, len);
      }
      bos.flush();
      } catch (Exception e) {
      }finally{
      CloseUtil.closeIO(sis);
      CloseUtil.closeIO(bos);
      }
      }
      /
      *
    • SequenceInputStrea序列输入流;Enumeration枚举;elements元素
    • @param elements
    • @return
      */

    private SequenceInputStream SequenceInputStream(Enumeration elements) {

     return null;
    

    }
    public static void main(String[] args) {
    //SplitFile file = new SplitFile(“E:/xp/2020/test/char.java”,50,“E:/xp/2020”);
    //其他文件名的分割与合并
    SplitFile2 file = new SplitFile2(“E:/xp/2020/学员设置(2020).xls”,“E:/xp/2020”,51);
    //System.out.println(file.size);

     //file.split("E:/xp/2020");
     //其他文件名的分割与合并;先分割后合并
     file.split();
     file.merge2("E:/xp/2020/test1.xls");
    

    }
    }
    //-------------------------------------------------
    package IO流_167_文件分割与合并_文件合并;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.RandomAccessFile;
import java.io.SequenceInputStream;

public class CloseUtil {

public static void closeIO(BufferedOutputStream bos, RandomAccessFile raf) {
	// TODO Auto-generated method stub
	
}

public static void closeIO(BufferedInputStream bis) {
	// TODO Auto-generated method stub
	
}
public static void closeIO(BufferedOutputStream bos) {
	// TODO Auto-generated method stub
	
}

public static void closeIO(SequenceInputStream sis) {
	// TODO Auto-generated method stub
	
}

}
//结果-------------------------------------------------
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值