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

使用Parquet.Net读取Parquet文件时遇‘Destination is too short’错误求助

C#读取Parquet转JSON时出现"Destination is too short"错误的排查与解决

问题描述

我正在开发一个C# API项目,需实现读取Parquet文件并转换为JSON格式的功能。平时常用Python,读取Parquet仅需一行代码,但作为C#新手遇到了问题:程序先下载S3上的Parquet文件到临时文件,后续在DataColumn column = await groupReader.ReadColumnAsync(dataFields[c]);行报错。

用Python的pd.read_parquet(filename)读取同文件显示正常,文件含90000行、30列,所有列均为float64类型。

错误信息

System.ArgumentException
  HResult=0x80070057
  Message=Destination is too short. (Parameter 'destination')
  Source=System.Private.CoreLib
  StackTrace:
   at System.ThrowHelper.ThrowArgumentException_DestinationTooShort()
   at Parquet.Encodings.ParquetPlainEncoder.Decode(Span`1 source, Span`1 data)
   at Parquet.Encodings.ParquetPlainEncoder.Decode(Array data, Int32 offset, Int32 count, SchemaElement tse, Span`1 source, Int32& elementsRead)
   at Parquet.File.DataColumnReader.ReadColumn(Span`1 src, Encoding encoding, Int64 totalValuesInChunk, Int32 totalValuesInPage, PackedColumn pc)
   at Parquet.File.DataColumnReader.<ReadDataPageV1Async>d__13.MoveNext()
   at Parquet.File.DataColumnReader.<ReadAsync>d__8.MoveNext()
   at ConvertController.<ConvertToJSON>d__2.MoveNext() in C:\Users\myuser\Desktop\repos\frontend\project\Controllers\WebAPI_ParquetController.cs:line 78

  This exception was originally thrown at this call stack:
    [External Code]
    ConvertController.ConvertToJSON(string) in WebAPI_ParquetController.cs

相关代码片段

// Open the parquet file stream
using (Stream fileStream = System.IO.File.OpenRead(tempFilePath))
{
    // Open parquet file reader
    using (ParquetReader parquetReader = await ParquetReader.CreateAsync(fileStream))
    {
        // Get file schema
        DataField[] dataFields = parquetReader.Schema.GetDataFields();

        var result = new List<Dictionary<string, object>>();

        // Enumerate through row groups in this file
        for (int i = 0; i < parquetReader.RowGroupCount; i++)
        {
            // Create row group reader
            using (ParquetRowGroupReader groupReader = parquetReader.OpenRowGroupReader(i))
            {
                var rowGroupResult = new Dictionary<string, object>();

                // Read all columns inside each row group
                for (int c = 0; c < dataFields.Length; c++)
                {
                    DataColumn column = await groupReader.ReadColumnAsync(dataFields[c]); ///ERROR

                    // Cast column data to the appropriate type
                    var columnData = column.Data;
                    var decodedData = new object[columnData.Length];
                    // Decode the column data
                    for (int idx = 0; idx < columnData.Length; idx++)
                    {
                        decodedData[idx] = column.Data.GetValue(idx);
                    }
                    string columnName = dataFields[c].Name;

                    rowGroupResult[columnName] = decodedData;
                }

                result.Add(rowGroupResult);
            }
        }

        // Convert the result to JSON
        var jsonResult = JsonConvert.SerializeObject(result);

        return Ok(jsonResult);
    }
}

错误原因分析

这个错误是Parquet解码过程中,分配的目标缓冲区长度不足以容纳解码后的数据导致的,常见触发场景:

  • 库版本问题:旧版本Parquet.Net库在处理特定编码或大数量级列时,存在缓冲区计算逻辑缺陷
  • Schema解析偏差:虽然Python识别为float64,但C#端自动解析的Schema可能和文件实际元数据存在细微差异(比如空值标识、精度定义)
  • 行组数据量过大:单个行组的数据量超出了库默认的缓冲区处理上限

解决方法

  • 升级Parquet.Net库:该问题在较新版本中已被修复,通过NuGet将Parquet.Net包更新到最新稳定版
  • 显式指定数据类型:已知所有列都是float64,手动指定读取类型避免Schema解析偏差,修改代码如下:
    // 替换原Schema获取代码
    var dataFields = parquetReader.Schema.GetDataFields()
        .Select(df => new DataField<double>(df.Name))
        .ToArray();
    
  • 验证临时文件完整性:确认从S3下载的临时文件未损坏,可通过对比文件哈希值验证
  • 调整读取逻辑:若行组数据量过大,可尝试分批次读取列数据,或查看库文档调整缓冲区配置参数

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 22:44:55