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

C#写入Apache Arrow文件在Julia/Python读取时的Footer异常问题

问题:C#写入Apache Arrow文件后跨语言读取失败

问题重现

1. C#写入Struct Array到Arrow文件的代码

var structField = new StructType(
    new []
    {
        new Field("field1", new StringType(), nullable: false),
        new Field("field2", new Int64Type(), nullable: false)
    });

StringArray stringArray = new StringArray.Builder()
    .AppendRange(new[] {"angel", "bobby", "charlie"})
    .Build();
Int64Array intArray = new Int64Array.Builder()
    .AppendRange(new[] { 1L,2,3 })
    .Build();

StructArray structs = new StructArray(structField, 3, new IArrowArray[] { stringArray, intArray }, ArrowBuffer.Empty, nullCount: 0);

var recordBatch = new Apache.Arrow.RecordBatch.Builder()
    .Append("col1", false, structs)
    .Build();

using (var stream = File.OpenWrite("test.arrow"))
using (var writer = new Apache.Arrow.Ipc.ArrowFileWriter(stream, recordBatch.Schema, true))
{
    await writer.WriteRecordBatchAsync(recordBatch);
    await writer.WriteEndAsync();
}

2. Julia读取时的错误

执行代码:

using Arrow
table = Arrow.Table("test.arrow")
@show table
@show table[1]

报错信息:

ERROR: LoadError: MethodError: no method matching iterate(::Nothing)
Closest candidates are:
  iterate(::Union{LinRange, StepRangeLen}) at range.jl:872
  iterate(::Union{LinRange, StepRangeLen}, ::Integer) at range.jl:872
  iterate(::T) where T<:Union{Base.KeySet{<:Any, <:Dict}, Base.ValueIterator{<:Dict}} at dict.jl:712
  ...
Stacktrace:
 [1] getdictionaries!(dictencoded::Dict{Int64, Arrow.Flatbuf.Field}, field::Arrow.Flatbuf.Field)
   @ Arrow ~/.julia/packages/Arrow/P0wVk/src/table.jl:409
 [2] getdictionaries!(dictencoded::Dict{Int64, Arrow.Flatbuf.Field}, field::Arrow.Flatbuf.Field)
   @ Arrow ~/.julia/packages/Arrow/P0wVk/src/table.jl:410
 [3] macro expansion
   @ ~/.julia/packages/Arrow/P0wVk/src/table.jl:339 [inlined]
 [4] macro expansion
   @ ./task.jl:454 [inlined]
 [5] Arrow.Table(blobs::Vector{Arrow.ArrowBlob}; convert::Bool)
   @ Arrow ~/.julia/packages/Arrow/P0wVk/src/table.jl:321
 [6] Table
   @ ~/.julia/packages/Arrow/P0wVk/src/table.jl:295 [inlined]
 [7] #Table#98
   @ ~/.julia/packages/Arrow/P0wVk/src/table.jl:290 [inlined]
 [8] Table (repeats 2 times)
   @ ~/.julia/packages/Arrow/P0wVk/src/table.jl:290 [inlined]
 [9] top-level scope

使用Stream读取也出现类似错误:

stream = Arrow.Stream("test.arrow")
for d in stream
    @show d
end

3. Python读取时的错误

执行代码:

import pyarrow.feather as feather
table = feather.read_table("test.arrow")
print(table[0])

报错信息:

OSError: Verification of flatbuffer-encoded Footer failed.

问题原因及解决方法

原因分析

问题出在StructArray的构造参数上:原代码传递了ArrowBuffer.Empty作为validity buffer,但根据Apache Arrow规范,当字段没有null值(nullCount:0)时,validity buffer应该不存在(即传递null)。传递空的buffer会导致生成的Arrow文件结构不符合规范,进而引发跨语言读取时的Footer验证失败或结构解析错误。

解决代码

修改StructArray的创建代码,移除ArrowBuffer.Empty参数(或替换为null):

// 方法1:省略validityBuffer参数,使用默认值null
StructArray structs = new StructArray(structField, 3, new IArrowArray[] { stringArray, intArray }, nullCount: 0);

// 方法2:显式传递null作为validityBuffer
StructArray structs = new StructArray(structField, 3, new IArrowArray[] { stringArray, intArray }, null, nullCount: 0);

修改后重新生成Arrow文件,即可在Julia和Python中正常读取。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 08:35:01