Java 高效大文件 读取&写入(一亿行)

您所在的位置:网站首页 javaweb多线程上传大文件 Java 高效大文件 读取&写入(一亿行)

Java 高效大文件 读取&写入(一亿行)

#Java 高效大文件 读取&写入(一亿行)| 来源: 网络整理| 查看: 265

写文件

需求:写入1亿行,7位以内的随机的数字。

首先看成果图,代表没骗大家!!!!!

这个是最终生成的文件,有770多MB 。下面用glogg打开预览:

程序打印耗时

7149ms + 923 ms = 8072ms ,也就是8秒,写入1个亿数据到文件!!!!(还可以参数调优)

思想

利用nio高效写文件,先写入20个小文件,最后合并,每个小文件开一个线程。

代码:

public static void main(String[] args) throws CloneNotSupportedException, InterruptedException, IOException { int totals = 100000000; int segment = 20 ; // 写入5亿条数据 // 开启20个线程 ExecutorService service = Executors.newFixedThreadPool(segment); AtomicInteger incr = new AtomicInteger(0); CountDownLatch downLatch = new CountDownLatch(segment); long s = System.currentTimeMillis(); for(int j=0;j{ RandomAccessFile acf; FileChannel fc = null ; try { String fName = "E:\\tmp_" + incr.getAndIncrement()+".txt"; acf = new RandomAccessFile(fName, "rw"); fc = acf.getChannel(); int offset = 0; for (int i = 0; i { //这里千万不要 打印 line , 太耗时了 total.getAndIncrement(); }); } finally { downLatch.countDown(); } }); } downLatch.await(); System.out.println("读取文件总耗时:" + (System.currentTimeMillis() - s) + " , 读取数据行:" + total.get()); service.shutdown(); } /** * 按行分割文件 * * @param sourceFilePath 为源文件路径 * @param targetDirectoryPath 文件分割后存放的目标目录 * @param rows 为多少行一个文件 */ public static int splitFileByLine(String sourceFilePath, String targetDirectoryPath, int rows) { String sourceFileName = sourceFilePath.substring(sourceFilePath.lastIndexOf(File.separator) + 1, sourceFilePath.lastIndexOf("."));// 源文件名 String splitFileName = targetDirectoryPath + File.separator + sourceFileName + "-%s.txt";// 切割后的文件名 File targetDirectory = new File(targetDirectoryPath); if (!targetDirectory.exists()) { targetDirectory.mkdirs(); } PrintWriter pw = null;// 字符输出流 String tempLine; int lineNum = 0;// 本次行数累计 , 达到rows开辟新文件 int splitFileIndex = 1;// 当前文件索引 try (BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(sourceFilePath)))) { pw = new PrintWriter(String.format(splitFileName, splitFileIndex)); while ((tempLine = br.readLine()) != null) { if (lineNum > 0 && lineNum % rows == 0) {// 需要换新文件 pw.flush(); pw.close(); pw = new PrintWriter(String.format(splitFileName, ++splitFileIndex)); } pw.write(tempLine + "\n"); lineNum++; } return splitFileIndex; } catch (Exception e) { e.printStackTrace(); return -1; } finally { if (null != pw) { pw.flush(); pw.close(); } } } public interface Callback { public void onReceive(String line); } /** * 大文件读取 * * @param filePath */ public static void readFile(String filePath, Callback callback) { File file = new File(filePath); BufferedReader reader = null; try { reader = new BufferedReader(new FileReader(file), 20 * 1024 * 1024); // 如果是读大文件,设置缓存 String tempString = null; while ((tempString = reader.readLine()) != null) { callback.onReceive(tempString); } reader.close(); } catch (IOException e) { e.printStackTrace(); } finally { if (reader != null) { try { reader.close(); } catch (IOException e) { e.printStackTrace(); } } } } 读取待优化点

可以换成NIO的切割文件方式,这是我读取一亿行数据耗时结果图:

切分成20个文件,耗时 :743ms 。 加上读取一起耗时: 3252 ms。 有质的提升!!!

切分后的文件截图:

NIO切割指定的是字节数, 这里要进行一定的操作(避免将一行的整数切分到两个不同的文件)

源码在这个上面。写代码不容易,需要花6块钱 购买切分的源码,维持生计,谢谢!!!

交流 可以联系我QQ: 657455400



【本文地址】


今日新闻


推荐新闻


    CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3