A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

© 15127673623 中级黑马   /  2016-5-4 23:00  /  355 人查看  /  0 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

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);
        }
}

0 个回复

您需要登录后才可以回帖 登录 | 加入黑马