美文网首页Java 杂谈
Java 超大文件排序

Java 超大文件排序

作者: 叫我宫城大人 | 来源:发表于2019-07-12 10:45 被阅读13次

思想

  1. 超大文件无法一次性全部加载到内存中;
  2. 可以将超大文件分片排序,然后遍历分片,输出排序后内容至指定文件;

编码

创建超大文件

private static void createBigFile() {
    Random random = new Random();
    try (FileWriter writer = new FileWriter(BIG_FILE_NAME)) {
        for (int i = 0; i < LINE_COUNT; i++) {
            int val = random.nextInt(Integer.MAX_VALUE);
            writer.write(val + LINE_SEPARATOR);
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
}

超大文件分片排序

private static List<String> separateFile() {
    List<String> fileNameList = new ArrayList<>();
    try (BufferedReader reader = new BufferedReader(new FileReader(BIG_FILE_NAME))) {
        int index = 0;
        List<Integer> batchLineList = new ArrayList<>(BATCH_SIZE);
        String line;
        while ((line = reader.readLine()) != null) {
            batchLineList.add(Integer.valueOf(line));
            if (batchLineList.size() == BATCH_SIZE) {
                // 内容排序
                batchLineList.sort(Comparator.comparingInt(a -> a));
                // 写小文件
                String fileName = BIG_FILE_NAME + ".tmp." + index++;
                try (FileWriter tmpWriter = new FileWriter(fileName)) {
                    for (Integer val : batchLineList) {
                        tmpWriter.write(val + LINE_SEPARATOR);
                    }
                }
                fileNameList.add(fileName);
                batchLineList.clear();
            }
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
    return fileNameList;
}

分片合并输出

private static void mergeFile(List<String> fileNameList) {
    Map<BufferedReader, String> map = new HashMap<>();
    try (FileWriter writer = new FileWriter(SORT_FILE_NAME)) {
        for (String fileName : fileNameList) {
            BufferedReader tmpReader = new BufferedReader(new FileReader(fileName));
            map.put(tmpReader, tmpReader.readLine());
        }
        while (true) {
            boolean canRead = false;
            Map.Entry<BufferedReader, String> minEntry = null;
            for (Map.Entry<BufferedReader, String> entry : map.entrySet()) {
                String value = entry.getValue();
                if (value == null) {
                    continue;
                }
                // 获取当前 reader 内容最小 entry
                if ((minEntry == null) || (Integer.valueOf(value) < Integer.valueOf(minEntry.getValue()))) {
                    minEntry = entry;
                }
                canRead = true;
            }
            // 当且仅当所有 reader 内容为空时,跳出循环
            if (!canRead) {
                break;
            }
            writer.write(minEntry.getValue() + LINE_SEPARATOR);
            minEntry.setValue(minEntry.getKey().readLine());
        }
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        // 注意关闭分片文件输入流
        for (BufferedReader reader : map.keySet()) {
            try {
                reader.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

相关文章

  • Java 超大文件排序

    思想 超大文件无法一次性全部加载到内存中; 可以将超大文件分片排序,然后遍历分片,输出排序后内容至指定文件; 编码...

  • E1.2 Go语言实现超大文本文件按行排序和去重复行

    对超大文本文件进行排序(这里的排序一般指按行进行排序),是一种很特殊需求,这种“超大”的文本文件一般是指远远超出内...

  • 外部排序 || 内存放不下了= =

    外部排序:归并排序 根据内存缓冲区大小,将外存上含有n个记录(n超超超大)的文件分成若干长度为h的子文件。依次读入...

  • FileSnap

    FileSnap.java 找到100个snapshot文件,按zxid降序排序遍历找到的snapshot文件,从...

  • java导出超大 excel 文件

    结论 通过 POI的SXSSFWorkbook,使用操作系统的临时文件来作为缓存,可以生成超大的excel 文件(...

  • Java比较器(对象排序)

    Java实现排序的方式 自然排序:java.lang.Comparable 定制排序:java.lang.Comp...

  • java排序方法资料

    java排序,效率高的是哪种排序方法 JAVA快速排序(高效) java中常用的几种排序算法 相关代码: /* *...

  • 面试知识点

    排序冒泡排序快速排序选择排序插入排序二路归并 查找二分查找 排序和查找的java实现 java语言Java字符串字...

  • 数据结构&算法(一)

    一、Java实现快速排序算法 二、Java实现折半插入排序算法 三、Java实现冒泡排序算法

  • Java 排序

    概述 ​对Java对数组对象进行排序,Java对排序问题的处理。Java排序一般包括基础排序和Lambda Com...

网友评论

    本文标题:Java 超大文件排序

    本文链接:https://www.haomeiwen.com/subject/ditekctx.html