1. 程式人生 > 其它 >《JAVA300集》IO流_檔案分割-day18

《JAVA300集》IO流_檔案分割-day18

技術標籤:《JAVA300集》學習java檔案分割

目錄

檔案分割

(1)分塊讀取檔案、指定位置讀取剩餘全部內容、指定位置讀取剩餘部分內容

(2)同時實現讀取和寫入

(3) 用面向物件的思想封裝程式碼


檔案分割

RandomAccessFile

該類的例項支援讀取和寫入隨機訪問檔案。

(1)分塊讀取檔案、指定位置讀取剩餘全部內容、指定位置讀取剩餘部分內容

package Test_IO;
/*
* 三種隨機讀取方法
* */


import java.io.IOException;
import java.io.RandomAccessFile;
import java.io.File;

public class RandTest01 {
    public static void main(String[] args) throws IOException {
        //分塊讀取
        String path = "D:/Java/ZhuoQiu/src/Test_IO/DataTest.java";
        File src = new File(path);
        long allLen = src.length(); //總長度
        System.out.println(allLen);
        int blockSize = 512; //每塊大小
        int size = (int)Math.ceil(allLen*1.0/blockSize); //向上取整, 分多少塊
        int beginPos = 0; //起始位置
        int actualSize = (int)(blockSize>allLen?allLen:blockSize); //條件成立,執行:左邊
        for(int i=0;i<size;i++){
            beginPos = i*blockSize;
            if(i==size-1){ //最後一塊
                actualSize = (int)allLen; //len剩餘量
            }else{
                System.out.println(i);
                actualSize = blockSize;
                allLen -=actualSize;
            }
            System.out.println("i:"+i+" begin:"+beginPos+" len:"+allLen);  //完成分塊
            
            RandomAccessFile raf = new RandomAccessFile(new File(path), "r");//r表示read
            raf.seek(beginPos);
            //操作(分段讀取)
            byte[] flush = new byte[1024]; //緩衝容器
            int len = -1;
            while ((len = raf.read(flush)) != -1) {
                if (actualSize > len) {
                    System.out.println(new String(flush, 0, len));
                    actualSize -= len;
                }else{
                    System.out.println(new String(flush, 0, actualSize));
                    break;
                }
            }
            raf.close();
        }
    }

    //指定起始位置,讀取剩餘的所有內容
    public static void test1() throws IOException{
        String path = "D:/Java/ZhuoQiu/src/Test_IO/DataTest.java";
        RandomAccessFile raf = new RandomAccessFile(new File(path),"r");//r表示read
        //隨機讀取
        raf.seek(2);//從第二個位置開始
        //讀取
        //操作(分段讀取)
        byte[] flush = new byte[1024]; //緩衝容器
        int len = -1;
        while((len=raf.read(flush))!=-1){
            System.out.println(new String(flush,0,len));
        }
        raf.close();
    }

    //指定起始位置,讀取剩餘一定大小的內容
    public static void test2() throws IOException {
        String path = "D:/Java/ZhuoQiu/src/Test_IO/DataTest.java";
        RandomAccessFile raf = new RandomAccessFile(new File(path), "r");//r表示read
        //起始位置
        int beginPos = 2;
        //實際大小
        int actualSize = 1026;

        raf.seek(beginPos);
        //讀取
        //操作(分段讀取)
        byte[] flush = new byte[1024]; //緩衝容器
        int len = -1;
        while ((len = raf.read(flush)) != -1) {
            if (actualSize > len) {
                System.out.println(new String(flush, 0, len));
                actualSize -= len;
            }else{
                System.out.println(new String(flush, 0, actualSize));
                break;
            }
        }
        raf.close();
    }
}

(2)同時實現讀取和寫入

import java.io.IOException;
import java.io.RandomAccessFile;
import java.io.File;

public class RandTest02 {
    public static void main(String[] args) throws IOException {
        //分塊讀取
        String path = "D:/Java/ZhuoQiu/src/Test_IO/DataTest.java";

        RandomAccessFile raf = new RandomAccessFile(new File(path), "r");//r表示read
        RandomAccessFile raf2 = new RandomAccessFile(new File("print.txt"), "rw");//rw表示write


        long allLen = raf.length(); //總長度
        System.out.println(allLen);
        int blockSize = 512; //每塊大小
        int size = (int) Math.ceil(allLen * 1.0 / blockSize); //向上取整, 分多少塊
        int beginPos = 0; //起始位置
        int actualSize = (int) (blockSize > allLen ? allLen : blockSize); //條件成立,執行:左邊

        for (int i = 0; i < size; i++) {
            beginPos = i * blockSize;
            if (i == size - 1) { //最後一塊
                actualSize = (int) allLen; //len剩餘量
            } else {
                System.out.println(i);
                actualSize = blockSize;
                allLen -= actualSize;
            }

            System.out.println("i:" + i + " begin:" + beginPos + " len:" + allLen);  //完成分塊
            raf.seek(beginPos);
            //操作(分段讀取)
            byte[] flush = new byte[1024]; //緩衝容器
            int len = -1;
            while ((len = raf.read(flush)) != -1) {
                if (actualSize > len) {
                    raf2.write(flush, 0, len);
                    actualSize -= len;
                } else {
                    raf2.write(flush, 0, actualSize);
                    break;
                }
            }
        }
        raf2.close();
        raf.close();
    }
}

(3) 用面向物件的思想封裝程式碼

(加入了檔案合併)

package Test_IO;

import java.io.*;
import java.util.ArrayList;
import java.util.List;

public class SpliteFile {
    //源頭
    private File src;
    //目的地(資料夾)
    private String destDir;
    //所有分割後的檔案儲存路徑
    private List<String> destPaths;
    //每塊大小
    private int blockSize;
    //塊數
    private int size;


    public SpliteFile(String srcPath, String destDir, int blockSize) {
        this.src = new File(srcPath);
        this.destDir = destDir;
        this.blockSize = blockSize;
        this.destPaths = new ArrayList<String>();

        //初始化
        init();
    }

    //初始化
    private void init() {
        long len = this.src.length();
        this.size = (int) Math.ceil(len * 1.0 / blockSize);
        for (int i = 0; i < size; i++) {
            this.destPaths.add(this.destDir + "/"+ i + "-" + this.src.getName());
        }

    }

    //分割
    public void split() throws IOException {
        long allLen = src.length(); //總長度
        int size = (int) Math.ceil(allLen * 1.0 / blockSize); //向上取整, 分多少塊
        int beginPos = 0; //起始位置
        int actualSize = (int) (blockSize > allLen ? allLen : blockSize); //條件成立,執行:左邊

        for (int i = 0; i < size; i++) {
            beginPos = i * blockSize;
            if (i == size - 1) { //最後一塊
                actualSize = (int) allLen; //len剩餘量
            } else {
                System.out.println(i);
                actualSize = blockSize;
                allLen -= actualSize;
            }
            splitDetail(i,beginPos,actualSize);
        }
    }
    private void splitDetail(int i, int beginPos, int actualSize) throws IOException {
        RandomAccessFile raf = new RandomAccessFile(this.src, "r");
        RandomAccessFile raf2 = new RandomAccessFile(this.destPaths.get(i), "rw");
        System.out.println(this.destPaths.get(i));
//        OutputStream raf2 = new FileOutputStream(this.destPaths.get(i));
        raf.seek(beginPos);
        //操作(分段讀取)
        byte[] flush = new byte[1024]; //緩衝容器
        int len = -1;
        while ((len = raf.read(flush)) != -1) {
            if (actualSize > len) {
                raf2.write(flush, 0, len);
                actualSize -= len;
            } else {
                raf2.write(flush, 0, actualSize);
                break;
            }
        }
        raf2.close();
        raf.close();
    }

    public void merge(String destPath) throws IOException {
        //輸出流
        OutputStream os = new BufferedOutputStream(new FileOutputStream(destPath,true));
        //輸入流
        for(int i =0;i<destPaths.size();i++){
            InputStream is = new BufferedInputStream(new FileInputStream(destPaths.get(i)));

            //拷貝
            byte[] flush = new byte[1024];
            int len = -1;
            while((len=is.read(flush))!=-1){
                os.write(flush,0,len);
            }
            os.flush();
            is.close();
        }
        os.close();
    }
    public static void main(String[] args) throws IOException {
        String srcPath =  "D:/Java/ZhuoQiu/src/Test_IO/DataTest.java";
        String destDir = "D:/Java/ZhuoQiu/src/dest";
        SpliteFile sf = new SpliteFile(srcPath, destDir, 1024);
        sf.split();
    }
}