天天看點

SequenceInputStream序列流 用于合并多個檔案2. SequenceInputStream

2. SequenceInputStream

- - - - | InputStream  所有輸入位元組流的基類  抽象類

- - - - - - - - | FileInputStream 讀取檔案資料的輸入位元組流

- - - - - - - - | BufferedInputStream  緩沖輸入位元組流。

- - - - - - - - | SequenceInputStream 序列輸入位元組流

1、SequenceInputStream 表示其他輸入流的邏輯串聯。

它從輸入流的有序集合開始,并從第一個輸入流開始讀取,直到到達檔案末尾,接着從第二個輸入流讀取,依次類推,直到到達包含的最後一個輸入流的檔案末尾為止。

2、SequenceInputStream 的構造方法:

  1. SequenceInputStream(Enumeration<? extends InputStream> e):用于合并多個檔案

            通過記住參數來初始化新建立的 SequenceInputStream,該參數必須是生成運作時類型為 InputStream 對象的 Enumeration 型參數。

  1. SequenceInputStream(InputStream s1, InputStream s2):用于合并兩個檔案

            通過記住這兩個參數來初始化新建立的 SequenceInputStream(将按順序讀取這兩個參數,先讀取 s1,然後讀取 s2),以提供從此 SequenceInputStream 讀取的位元組。

3、SequenceInputStream的使用步驟

  1. 找到目标檔案
  2. 搭建資料通道
    1. 建立Vector集合,将攜帶資料的流對象以元素的形式添加到集合中
    2. 使用Vector集合的elements()方法獲得疊代器。
    3. 将疊代器傳入SequenceInputStream序列流中
  3. 傳輸資料
  4. 關閉資源

4、案例

需求:将E:\\aa\\music下的所有檔案合并成一個檔案,然後儲存到E:\\aa下

// 将E:\\aa\\music下的所有檔案合并成一個檔案,然後儲存到E:\\aa下
public class Dome3 {
    public static void main(String[] args) throws IOException {
        // 1.找到目标檔案
        File inFile = new File("E:\\aa\\music");// 源檔案1
        File outFile = new File("E:\\aa\\合并.mp3");//輸出目标檔案

        // 2.搭建傳輸通道
        FileOutputStream fileOutputStream = new FileOutputStream(outFile);//輸出流

        Vector<FileInputStream> vector = new Vector<FileInputStream>();//建立Vector集合
        File[] files = inFile.listFiles();//擷取music檔案夾下的所有檔案的集合
        // 讀取檔案中的資料,并加入vector集合中
        for (File file : files) {//周遊集合
            vector.add(new FileInputStream(file));//将所有檔案都添加到vector集合中
        }
        Enumeration<FileInputStream> elements = vector.elements();//擷取集合的疊代器
        SequenceInputStream sequenceInputStream = new SequenceInputStream(elements);//将疊代器傳入SequenceInputStream序列流中
       
        byte[] bytes = new byte[1024 * 10];//緩沖數組,用于存儲輸入流讀取的資料,提高讀取效率
        int len = 0;// 用于存儲每次從檔案中讀取的位元組個數
        while ((len = sequenceInputStream.read(bytes)) != -1) {//從序列流中讀取資料放入緩存數組中
            fileOutputStream.write(bytes, 0, len);//将緩存數組中的資料寫出到硬碟中。
        }

        // 釋放資源,先開後關原則
        sequenceInputStream.close();
        fileOutputStream.close();
    }
}
           

5.合并切割檔案

// 将一首歌曲切割開,然後再合并起來,要求不影響資料大小
public class Dome2 {
    // 程式入口
    public static void main(String[] args) {
        incise();//切割檔案
        merge();//合并檔案
    }

    // 切割檔案
    public static void incise() {
        FileInputStream fileInputStream = null;//輸入流
        FileOutputStream fileOutputStream = null;//輸出流

        try {
            // 找到目标檔案
            File sourceFile = new File("E:\\aa\\野狼disco.mp3");//目标檔案
            //File sourceFile = new File("E:\\aa\\A.java");//讀取目标檔案
            File dir = new File("E:\\aa\\music");//輸出目标檔案

            // 判斷輸出目标檔案夾是否存在,如果不存在則建立dir檔案夾,如果存在則删除其中相關檔案
            if (!dir.exists() || dir.isFile()) {
                dir.mkdirs();//如果dir不存在或dir是檔案,則建立dir檔案夾
            } else {
                // 如果dir是檔案夾
                for (File f : dir.listFiles()) {// 疊代檔案夾中的檔案
                    if (f.getName().matches("^野狼disco\\d+\\.mp3$")) {
                        f.delete();
                    }
                }
            }

            // 搭建通道
            fileInputStream = new FileInputStream(sourceFile);

            // 傳輸資料
            byte[] bytes = new byte[1024 * 1000];//緩沖數組
            int len = 0;//存儲每次讀取的資料
            int count = 1;//記錄切割數量
            while ((len = fileInputStream.read(bytes)) != -1) {
                // 每當從緩沖數組寫出一次資料,就建立一個檔案存儲,是以需要重新建立輸出流對象,從新找到輸出目标檔案
                fileOutputStream = new FileOutputStream(new File(dir, "野狼disco" + count + ".mp3"));
                fileOutputStream.write(bytes, 0, len);//向硬碟寫出資料
                fileOutputStream.close();//需要建立新檔案時,需要将不再使用的流關閉
                count++;
            }
        } catch (FileNotFoundException e) {
            throw new RuntimeException(e);
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            try {
                // 關閉資源
                fileInputStream.close();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    }


    //合并檔案
    public static void merge() {
        // 找到目标檔案
        File sourceFile = null;//輸入目标
        File destinationFile = null;//輸出目标
        FileOutputStream fileOutputStream = null;//輸出流
        SequenceInputStream sequenceInputStream = null;//序列流
        File[] files = null;//用于接受檔案夾中檔案的數組
        //搭建資料通道
        try {
            sourceFile = new File("E:\\aa\\music");
            destinationFile = new File("E:\\aa\\野狼disco(合并).mp3");
            fileOutputStream = new FileOutputStream(destinationFile, true);//檔案輸出目标

            // 判斷目标檔案是否存在
            if (sourceFile.exists()) {
                files = sourceFile.listFiles();// 擷取檔案夾中的檔案集合
                System.out.println("擷取檔案夾中檔案");
            } else {
                System.out.println("music檔案夾不存在...");
                return;
            }
            //判斷輸出目标檔案是否存在
            if (!destinationFile.exists()) {
                destinationFile.mkdirs();
            }

            // 傳輸資料
            Vector<FileInputStream> vector = new Vector<FileInputStream>();
            // 周遊檔案,并将檔案資料添加到集合中
            for (File file : files) {
                if (file.getName().matches("^野狼disco\\d+\\.mp3$")) {
                    vector.add(new FileInputStream(file));//将輸入流讀取到的符合規則的檔案的資料,添加到vector集合中。
                }
            }
            Enumeration<FileInputStream> elements = vector.elements();//通過Vector擷取疊代器
            sequenceInputStream = new SequenceInputStream(elements);//将疊代器傳入序列流

            byte[] bytes = new byte[1024 * 8];//緩沖數組
            int len = 0;//用于存儲每次讀取到的資料
            while ((len = sequenceInputStream.read(bytes)) != -1) {// 通過序列流讀取檔案
                fileOutputStream.write(bytes, 0, len);
            }
        } catch (FileNotFoundException e) {
            throw new RuntimeException(e);
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            try {
                // 關閉資源
                fileOutputStream.close();
                sequenceInputStream.close();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    }
}
           

繼續閱讀