You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何高效计算List<String[]>转换为CSV后的总文件大小?

问题描述

我持有List<String[]>类型的csvRows数据行数组,以及String[]类型的csvHeaderRow表头数组。目标是计算将这些内容写入最终CSV文件后的总大小,需要累加所有数据内容、表头内容、逗号的总大小,同时csvRows中的大量列可能为null或空值(例如"Rick,,,,15,,4324,,,"),而csvHeaderRow始终是完全填充的。

我可以将所有内容写入ByteArrayOutputStream后计算字节数组长度,但希望编写更高效、简洁的代码。当前代码版本如下:

public long getNumOfFiles(List<String[]> csvRows, String[] csvHeaderRow){
    long totalSize = csvRows.stream().mapToLong(i -> {
            return Stream.of(i).mapToLong(str -> {
                if (StringUtils.isNotEmpty(str)) {
                    return str.getBytes().length;
                }
                return 0L;
            }).sum();
        }).sum();
        
                totalSize = totalSize + Stream.of(csvHeaderRow).mapToLong(str -> str.getBytes().length).sum();
                totalSize = totalSize + csvHeaderRow.length * csvRows.size() + 1; // 逗号数量
                long numOfFiles = (totalSize / MAX_FILE_SIZE_BYTES) + 1;
    return numOfFiles;
}

请问如何更高效地编写这段代码?


优化方案

现有代码的问题点

  1. Stream嵌套开销:两层Stream嵌套会带来额外的对象创建和遍历开销,数据量大时效率较低
  2. 字符集不明确:str.getBytes()使用平台默认字符集,不同环境下可能导致字节数计算不一致
  3. 逗号数量计算错误:原代码的逗号计算逻辑仅在特定列数和行数下巧合正确,通用场景下会出错
  4. 遗漏换行符大小:写入CSV时每行(包括表头)末尾的换行符未计入总大小,导致结果偏小

优化后的代码

import java.nio.charset.StandardCharsets;

public long getNumOfFiles(List<String[]> csvRows, String[] csvHeaderRow) {
    int columnCount = csvHeaderRow.length;
    int rowCount = csvRows.size();
    long totalSize = 0;

    // 计算表头的字节大小
    for (String header : csvHeaderRow) {
        totalSize += header.getBytes(StandardCharsets.UTF_8).length;
    }

    // 计算所有数据行的字节大小
    for (String[] row : csvRows) {
        for (String cell : row) {
            if (cell != null && !cell.isEmpty()) {
                totalSize += cell.getBytes(StandardCharsets.UTF_8).length;
            }
        }
    }

    // 计算逗号总大小:每行有(columnCount - 1)个逗号,共(rowCount + 1)行(表头+数据行)
    long commaTotal = (long) (columnCount - 1) * (rowCount + 1);
    totalSize += commaTotal;

    // 计算换行符总大小:每行结尾1个换行符(\n),共(rowCount + 1)行,UTF-8下占1字节
    // 若使用\r\n则改为 *2
    long newlineTotal = (long) (rowCount + 1);
    totalSize += newlineTotal;

    // 计算文件数量
    return (totalSize / MAX_FILE_SIZE_BYTES) + 1;
}

优化说明

  • 替换Stream为普通循环:避免Stream嵌套的额外开销,遍历效率更高,尤其适合大数据量场景
  • 明确指定字符集:使用StandardCharsets.UTF_8确保字节数计算的一致性,不受平台环境影响
  • 修正逗号计算逻辑:根据列数和总行数准确计算逗号总数,避免逻辑错误
  • 补充换行符计算:CSV文件每行结尾的换行符是必须的,这里默认使用\n(1字节),若需要兼容Windows的\r\n可改为乘以2
  • 简化代码结构:拆分计算步骤,逻辑更清晰,便于维护和调试
  • 减少中间变量操作:直接累加总大小,避免多次赋值带来的冗余

内容的提问来源于stack exchange,提问作者Nila

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 01:50:01