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

使用Mmap处理大文件后的数据解析与批量处理技术咨询

问题解答

问题1:解析Mmap得到的UInt8向量,以及行的对应关系

  • 你看到的Vector{UInt8}里的每个元素是文件中的单个字节,不是内存地址。比如0x30对应ASCII字符'0',0x2f对应'/',0x0a是换行符\n。
  • 单个元素≠文件的一行,一行是两个换行符(或文件开头到第一个换行符、最后一个换行符到文件结尾)之间的所有字节序列。
  • 解析方法:
    1. 若文件不大(但你的是3.5GB,不建议),可以直接转成字符串:str = String(a),再用split(str, '\n')分割成行。
    2. 大文件更高效的方式是先找到所有换行符的位置:
      newline_indices = findall(==(0x0a), a)
      
      然后通过这些索引分割出每行的字节区间,比如第i行的字节范围是prev_ind+1 : curr_ind(prev_ind是上一个换行符索引,初始为0),再将字节段转成字符串:String(a[start:end]),之后按列分隔符(比如你的数据里的/)拆分得到每列数据。

问题2:批量处理大文件,避免内存不足

方案一:基于Mmap的分批处理

如果坚持用Mmap,可按以下步骤实现:

using Mmap, DataFrames, CSV

s = open("C:/Users/a.bannerman/Desktop/code/TS_data/big.txt", "r")
a = Mmap.mmap(s)
newline_indices = findall(==(0x0a), a)
total_rows = length(newline_indices)

batch_size = 10000
for batch_start in 1:batch_size:total_rows
    batch_end = min(batch_start + batch_size - 1, total_rows)
    # 获取当前批次的行对应的字节范围
    row_ranges = []
    prev_idx = 0
    for i in batch_start:batch_end
        curr_idx = newline_indices[i]
        push!(row_ranges, prev_idx+1 : curr_idx)
        prev_idx = curr_idx
    end
    # 解析当前批次的行成DataFrame
    rows_data = []
    for r in row_ranges
        line_str = String(a[r])
        # 按分隔符拆分列(这里假设分隔符是/,根据你的数据调整)
        cols = split(line_str, '/')
        push!(rows_data, cols)
    end
    df = DataFrame(rows_data, :auto)
    # 重命名列(如果需要)
    rename!(df, ["col1", "col2", "col3", "col4", "col5"])
    # 保存为CSV
    CSV.write("batch_$(batch_start)_$(batch_end).csv", df)
    # 释放内存
    df = nothing
    rows_data = nothing
    GC.gc()
end

方案二:优化CSV.jl的批量处理(更推荐)

你给出的CSV.jl代码已经是懒加载的思路,可进一步优化确保内存高效:

using CSV, DataFrames

row_size = 10000
# 若文件无表头,添加header=false;指定分隔符delim=你的分隔符(比如'/')
for (batch_num, rows) in enumerate(Iterators.partition(CSV.Rows("C:/Users/a.bannerman/Desktop/code/TS_data/big.txt", delim='/', header=false), row_size))
    df = DataFrame(rows)
    # 处理数据(比如类型转换等)
    # 保存批次
    CSV.write("batch_$(batch_num).csv", df)
    # 释放内存
    df = nothing
    GC.gc()
end
  • CSV.Rows不会一次性加载全部数据,每次只加载当前批次的行,内存占用极低。
  • 务必指定正确的delim分隔符(根据你的数据格式调整,比如你的示例里有/,大概率是分隔符),否则解析会出错。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 10:25:33