案例 测试读取excel文件的read方法

.read(b, off, len):“将输入流中最多len个数据字节读入 byte数组。尝试读取len个字节,但读取的字节也可能小于该值。以整数形式返回实际读取的字节数。”

代码:

package com.jc.test;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 测试读取excel文件的read方法
 * @author wang-xiaoming
 *
 */
public class TestExcel2 {
    /**
     * 加锁
     */
    static final Lock lock = new ReentrantLock();
    
    // 选择一个根目录
    private static final String ROOT = "D:\\share\\test\\";
    // 要读取的excel文件名称
    private static final String PATH = ROOT + "office.xlsx";
    // 分批次读取到哪个文件中
    private static final String TIMES_PATH = ROOT + "officeTimes.xlsx";
    // 一次性读取到哪个文件中
    private static final String ONCE_PATH = ROOT + "officeOnce.xlsx";
    
    public static void main(String[] args) {
        
        // 要读取的文件流
        FileInputStream fis = null;
        // 用来打印一次性读取日志的读取流
        FileInputStream fisOnce = null;
        // 用于生成officeForOnce文件的写入流
        FileOutputStream fosOnce = null;
        // 用来打印分批次读取日志的读取流
        FileInputStream fisTimes = null;
        // 用于生成officeForTimes文件的写入流
        FileOutputStream fosTimes = null;
        
        try {
            fis = new FileInputStream(PATH);
            System.out.println("原文件位置:" + PATH);
            int allBytes = fis.available();
            System.out.println("文件总字节大小,allBytes=" + allBytes + "\n");
            
            File fileTimes = new File(TIMES_PATH);
            createNewFile(fileTimes, lock);
            fisTimes = new FileInputStream(fileTimes);
            System.out.println("新建文件位置:" + fileTimes.toString());
            fosTimes = new FileOutputStream(fileTimes);
            
            byte[] b = new byte[allBytes];
            int len = 2048;
            int readBytes = 0;
            int times = 0;
            int read = 1;
            while(read > 0){
                times ++;
                // 读取
                // “将输入流中最多len个数据字节读入 byte数组。尝试读取len个字节,但读取的字节也可能小于该值。以整数形式返回实际读取的字节数。”
                // 为什么单次读取有可能小于len,请参考:https://blog.csdn.net/pec0105/article/details/79856114
                read = fis.read(b, 0, len);
                if(read <= 0){
                    break;
                }
                
                // 写入
                fosTimes.write(b, 0, (allBytes - readBytes) > len? len:(allBytes - readBytes));
                // 累计读取到的字节大小
                readBytes += read;
                
                // 日志验证
                System.out.println("【分批次读取】:第" + times + "次读取文件,本次预计读取字节数len=" + len + ",实际读取字节数read=" + read + ",已读取总字节数readBytes=" + readBytes);
                System.out.println("【分批次写入】:第" + times + "次写入文件,本次写入后总字节数writeTimes=" + fisTimes.available() + "\n");
            }
            System.out.println("文件总字节大小,allBytes=" + fisTimes.available() + "\n");
            
            File fileOnce = new File(ONCE_PATH);
            createNewFile(fileOnce, lock);
            System.out.println("新建文件位置:" + fileOnce.toString());
            // 日志验证
            fisOnce = new FileInputStream(fileTimes);
            // 写入
            fosOnce = new FileOutputStream(fileOnce);
            fosOnce.write(b, 0, allBytes);
            System.out.println("【一次性写入】:一次性写入读取的字节数,writeOnce=" + fisOnce.available());
            System.out.println("文件总字节大小,allBytes=" + fisOnce.available());
        } catch (IOException e) {
            System.err.println(e.getMessage());
            Thread.currentThread().interrupt();
        } finally {
            // 一个 try-with-resources语句可以像普通的 try语句那样有 catch和 finally块。在try-with-resources语句中,任意的 catch或者 finally块都是在声明的资源被关闭以后才运行。
            // 上面这个问题应该如何验证或者如果不想在finally中关闭资源应如何改写,请参考:https://blog.csdn.net/fly910905/article/details/86093723?depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromBaidu-2&utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromBaidu-2
            // 这里还是不优雅了
            closeResource(fis);
            closeResource(fisOnce);
            closeResource(fisTimes);
            closeResource(fosOnce);
            closeResource(fosTimes);
        }
    }
    
    /**
     * 删除已存在的文件并创建新文件
     * @param file
     * @param lock
     */
    public static void createNewFile(File file, Lock lock){
        try {
            if(!lock.tryLock(2, TimeUnit.SECONDS)){
                System.out.println("获取锁失败");
            }
            if(file.exists()){
                Path path = Paths.get(file.getPath());
                Files.delete(path);
                System.out.println("旧文件已删除");
            }
            if(!file.createNewFile()){
                System.out.println("创建新文件失败");
            }
        } catch (IOException | InterruptedException e) {
            System.err.println(e.getMessage());
            Thread.currentThread().interrupt();
        }finally {
            lock.unlock();
        }
    }
    
    /**
     * 关闭读取流资源
     * @param fis
     */
    public static void closeResource(FileInputStream fis){
        if(fis != null){
            try {
                fis.close();
            } catch (IOException e) {
                System.err.println(e.getMessage());
                Thread.currentThread().interrupt();
            }
        }
    }
    
    /**
     * 关闭写入流资源
     * @param fos
     */
    public static void closeResource(FileOutputStream fos){
        if(fos != null){
            try {
                fos.close();
            } catch (IOException e) {
                System.err.println(e.getMessage());
                Thread.currentThread().interrupt();
            }
        }
    }
}

执行结果:

原文件位置:D:\share\test\office.xlsx
文件总字节大小,allBytes=9960

旧文件已删除
新建文件位置:D:\share\test\officeTimes.xlsx
【分批次读取】:第1次读取文件,本次预计读取字节数len=2048,实际读取字节数read=2048,已读取总字节数readBytes=2048
【分批次写入】:第1次写入文件,本次写入后总字节数writeTimes=2048

【分批次读取】:第2次读取文件,本次预计读取字节数len=2048,实际读取字节数read=2048,已读取总字节数readBytes=4096
【分批次写入】:第2次写入文件,本次写入后总字节数writeTimes=4096

【分批次读取】:第3次读取文件,本次预计读取字节数len=2048,实际读取字节数read=2048,已读取总字节数readBytes=6144
【分批次写入】:第3次写入文件,本次写入后总字节数writeTimes=6144

【分批次读取】:第4次读取文件,本次预计读取字节数len=2048,实际读取字节数read=2048,已读取总字节数readBytes=8192
【分批次写入】:第4次写入文件,本次写入后总字节数writeTimes=8192

【分批次读取】:第5次读取文件,本次预计读取字节数len=2048,实际读取字节数read=1768,已读取总字节数readBytes=9960
【分批次写入】:第5次写入文件,本次写入后总字节数writeTimes=9960

文件总字节大小,allBytes=9960

旧文件已删除
新建文件位置:D:\share\test\officeOnce.xlsx
【一次性写入】:一次性写入读取的字节数,writeOnce=9960
文件总字节大小,allBytes=9960

PS:我是爱整理有洁癖的代码王,有好的Java学习方法或教程欢迎留言呀!

posted @ 2020-04-11 15:50  王晓鸣  阅读(868)  评论(0编辑  收藏  举报