.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 TestExcel { /** * 加锁 */ static final Lock lock = new ReentrantLock(); // 选择一个根目录 private static final String ROOT = "D:\\share\\xiaoming\\EDP 开发\\EDP 1.6.1\\"; // 要读取的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; // 用于生成officeForTimes文件的写入流 FileOutputStream fosOnce = null; // 用来打印一次性读取日志的读取流 FileInputStream fisTimes = null; // 用于生成officeForOnce文件的写入流 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\xiaoming\EDP 开发\EDP 1.6.1\office.xlsx 文件总字节大小,allBytes=9960 旧文件已删除 新建文件位置:D:\share\xiaoming\EDP 开发\EDP 1.6.1\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\xiaoming\EDP 开发\EDP 1.6.1\officeOnce.xlsx 【一次性写入】:一次性写入读取的字节数,writeOnce=9960 文件总字节大小,allBytes=9960
PS:我是爱整理有洁癖的代码王,有好的Java学习方法或教程欢迎留言呀!
原文:https://www.cnblogs.com/huakaiyoushi/p/12680429.html