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

C#处理超300万行压缩文本文件IP查询时遇内存溢出问题

大压缩TXT文件内存溢出问题解决方案

你的代码核心问题是一次性将整个解压后的文件加载到内存(File.ReadAllText返回完整字符串、Split生成全量行数组),对于百万级行的大文件,必然触发System.OutOfMemoryException。下面是针对该问题的具体优化方案:

最优方案:流式解压+逐行处理

无需生成中间文件,直接从GZip流中逐行读取解析,全程仅在内存中保留当前处理的单行数据,彻底解决内存占用问题。

代码示例:

public List<string> GetCustomerIdsByIp(string compressedFilePath, string targetIp)
{
    var matchedIds = new List<string>();

    using (var fileStream = File.OpenRead(compressedFilePath))
    using (var gzipStream = new GZipStream(fileStream, CompressionMode.Decompress))
    using (var reader = new StreamReader(gzipStream))
    {
        string line;
        while ((line = reader.ReadLine()) != null)
        {
            // 假设行格式为"客户ID,IP地址,...",根据实际格式调整分割逻辑
            if (line.Contains(targetIp))
            {
                var segments = line.Split(',');
                if (segments.Length >= 2)
                {
                    matchedIds.Add(segments[0]);
                }
            }
        }
    }

    return matchedIds;
}

备选方案:保留中间文件时的逐行读取

如果业务需要保留解压后的文件,不要用File.ReadAllText一次性加载,改用File.ReadLines(返回IEnumerable<string>,逐行加载):

// 修改解压方法:只生成文件,不返回全量内容
public void DecompressFile(FileInfo compressedFile)
{
    string outputPath = compressedFile.FullName.Remove(compressedFile.FullName.Length - compressedFile.Extension.Length);
    
    using (var inputStream = compressedFile.OpenRead())
    using (var outputStream = File.Create(outputPath))
    using (var gzipStream = new GZipStream(inputStream, CompressionMode.Decompress))
    {
        gzipStream.CopyTo(outputStream);
    }
}

// 逐行读取解压后的文件
public List<string> SearchIpInDecompressedFile(string decompressedFilePath, string targetIp)
{
    var matchedIds = new List<string>();
    
    foreach (var line in File.ReadLines(decompressedFilePath))
    {
        if (line.Contains(targetIp))
        {
            var segments = line.Split(',');
            if (segments.Length >= 2)
            {
                matchedIds.Add(segments[0]);
            }
        }
    }
    
    return matchedIds;
}

额外优化提示

  • 精确IP匹配:避免用Contains(可能匹配到IP子串),建议提取行中IP部分后用IPAddress.TryParse解析,再做精确比对,减少误匹配。
  • 高效分割:如果行格式固定,可使用Span<char>进行分割,比string.Split更节省内存。
  • 多文件并行:处理多个文件时,可使用Parallel.ForEach并行处理不同文件,但单个文件内部保持逐行读取,避免内存叠加。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 14:43:22