import cn.hutool.core.convert.Convert;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.multipart.MultipartFile;

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

/**
 * @author fancl
 * @desc: 分块读取文件示例
 * @date 2022/8/10
 */
@Slf4j
public class BlockReadDemo {

    public static void main(String[] args) throws Exception {
        //write();
        String path = "D:/temp/3.txt";
        //先获取文件字节大小
        long fileTotalSize = getFileSize(path);
        int pageSize = 10;
        //根据总大小计算文件页数
        int pageNum = (int)(fileTotalSize + pageSize -1)/pageSize;
        log.info("总页数:" + pageNum);
        //文件大于0时读取
        if(fileTotalSize>0){
            //循环读取
            for(int current = 0; current<pageNum; current ++){
                byte[] bytes = readBlock(path, current);
                //字节数组转为字符串
                String readStr = new String(bytes);
                System.out.println("读取到：" + readStr);
                //把字节数组转为hex
                String hexStr = Convert.toHex(bytes);
                System.out.println("hexStr:" + hexStr);

            }
        }
    }

    //获取文件大小
    static long getFileSize(String path) {
        try {
            RandomAccessFile raf = new RandomAccessFile(path, "r");
            long length = raf.length();
            raf.close();
            return length;
        } catch (FileNotFoundException e) {
            return 0;
        }catch (IOException e){
            log.error(e.getMessage());
        }
        return 0;

    }

    //按位置分块读取文件内容
    static byte[] readBlock(String path, int pointer) throws Exception {
        //RandomAccessFile raf = new RandomAccessFile("D:/temp/startBasedata.sh", "r");
        //RandomAccessFile raf = new RandomAccessFile("D:/temp/2.txt", "r");
        RandomAccessFile raf = new RandomAccessFile(path, "r");
        long length = raf.length();
        System.out.println("文件大小：" + length);
        //设置指针的位置,每次有偏移
        int perSize = 10;
        raf.seek(pointer * perSize);
        //每次读取10字节,这个应该改为参数配置
        byte[] bytes = new byte[10];
        int readSize = raf.read(bytes);
        //如果没有读到10个字节，需要做数组拷贝
        //读取时判断是否还有剩余字节
        if (readSize < perSize) {
            byte[] copy = new byte[readSize];
            System.arraycopy(bytes, 0, copy, 0, readSize);
            raf.close();
            return copy;
        }
        raf.close();
        return bytes;
    }


    static void writeBlock(MultipartFile file) throws Exception {
        File fileupload = new File("");
        RandomAccessFile raf = new RandomAccessFile("D:\\t1.txt", "rw");
        raf.writeBytes("Hello World!234344444444444444444333\r\n");
        raf.writeBytes("3222222222222222222222222222");
        //raf.writeBoolean(true);
        //raf.writeInt(30);
        //raf.writeDouble(3.56);
        raf.close();
    }

}
