首页 > 代码库 > SequenceInputStream:序列流

SequenceInputStream:序列流

作用就是将多个读取流合并成一个读取流。实现数据合并。

表示其他输入流的逻辑串联。它从输入流的有序集合开始,并从第一个输入流开始读取,直到到达文件末尾,接着从第二个输入流读取,依次类推,直到到达包含的最后一个输入流的文件末尾为止。

这样做,可以更方便的操作多个读取流,其实这个序列流内部会有一个有序的集合容器,用于存储多个读取流对象。

该对象的构造函数参数是枚举,想要获取枚举,需要有Vector集合,但不高效。需用ArrayList,但ArrayList中没有枚举,只有自己去创建枚举对象。

但是方法怎么实现呢?因为枚举操作的是具体集合中的元素,所以无法具体实现,但是枚举和迭代器是功能一样的,所以,可以用迭代替代枚举。

 

合并原理:多个读取流对应一个输出流。

切割原理:一个读取流对应多个输出流。

 

import java.io.*;

import java.util.*;

class  SplitFileDemo{

    private static final String CFG = ".properties";

    private static final String SP = ".part";

    public static void main(String[] args) throws IOException{

       File file = new File("c:\\0.bmp");

       File dir = new File("c:\\partfiles");

       meger(dir);

    }

    //数据的合并。

    public static void meger(File dir)throws IOException{

       if(!(dir.exists() && dir.isDirectory()))

           throw new RuntimeException("指定的目录不存在,或者不是正确的目录");

       File[] files = dir.listFiles(new SuffixFilter(CFG));

       if(files.length==0)

           throw new RuntimeException("扩展名.proerpties的文件不存在");

       //获取到配置文件

       File config = files[0];

       //获取配置文件的信息。

       Properties prop = new Properties();

       FileInputStream fis = new FileInputStream(config);

       prop.load(fis);

       String fileName = prop.getProperty("filename");

       int partcount = Integer.parseInt(prop.getProperty("partcount"));

       //--------------------------

       File[] partFiles = dir.listFiles(new SuffixFilter(SP));

       if(partFiles.length!=partcount)

           throw new RuntimeException("缺少碎片文件");

       //---------------------

       ArrayList<FileInputStream> al = new ArrayList<FileInputStream>();

       for(int x=0; x<partcount; x++){

           al.add(new FileInputStream(new File(dir,x+SP)));

       }

       Enumeration<FileInputStream> en = Collections.enumeration(al);

       SequenceInputStream sis = new SequenceInputStream(en);

       File file = new File(dir,fileName);

       FileOutputStream fos = new FileOutputStream(file);

       byte[] buf = new byte[1024];

       int len = 0;

       while((len=sis.read(buf))!=-1){

           fos.write(buf,0,len);

       }

       fos.close();

       sis.close();

    }

    //带有配置信息的数据切割。

    public static void splitFile(File file)throws IOException{

       //用一个读取流和文件关联。

       FileInputStream fis = new FileInputStream(file);

       //创建目的地。因为有多个。所以先创建引用。

       FileOutputStream fos = null;

       //指定碎片的位置。

       File dir = new File("c:\\partfiles");

       if(!dir.exists())

           dir.mkdir();

       //碎片文件大小引用。

       File f = null;

       byte[] buf = new byte[1024*1024];

       //因为切割完的文件通常都有规律的。为了简单标记规律使用计数器。

       int count = 0;

       int len = 0;

       while((len=fis.read(buf))!=-1){

           f = new File(dir,(count++)+".part");

           fos = new FileOutputStream(f);

           fos.write(buf,0,len);

           fos.close();

       }

       //碎片文件生成后,还需要定义配置文件记录生成的碎片文件个数。以及被切割文件的名称。

       //定义简单的键值信息,可是用Properties。

       String filename = file.getName();

       Properties prop = new Properties();

       prop.setProperty("filename",filename);

       prop.setProperty("partcount",count+"");

       File config = new File(dir,count+".properties");

       fos = new FileOutputStream(config);

       prop.store(fos,"");

       fos.close();

       fis.close();

    }

}

class SuffixFilter implements FileFilter{

    private String suffix;

    SuffixFilter(String suffix){

       this.suffix  = suffix;

    }

    public boolean accept(File file){

       return  file.getName().endsWith(suffix);

    }

}

SequenceInputStream:序列流