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

关于使用Parquet-GLib编写Apache Parquet文件的技术咨询

关于使用Parquet-GLib编写Apache Parquet文件的技术咨询

嘿,我太懂这种对着API文档却无从下手的感觉了——光看接口定义确实很难拼凑出完整的读写流程。下面我给你整理了实操性强的代码示例和构建注意事项,帮你快速上手parquet-glib:

先搞定编译构建问题

parquet-glib基于GLib,所以编译时必须正确链接相关依赖。最省心的方式是用pkg-config自动获取编译参数,编译命令类似这样:

gcc your_parquet_code.c -o parquet_demo $(pkg-config --cflags --libs parquet-glib)

这个命令会自动包含parquet-glib和GLib的头文件路径,以及需要链接的库文件,不用手动写一堆-I和-L参数。

完整写入Parquet文件的示例

这个示例会创建一个包含id(整数)和name(字符串)两列的Parquet文件,写入两行数据:

#include <parquet-glib/parquet-glib.h>

int main() {
    // 初始化GLib的类型系统,GLib程序必备步骤
    g_type_init();

    // 第一步:定义Parquet的Schema
    GList *schema_fields = NULL;
    
    // 创建int32类型的"id"字段
    ParquetSchemaElement *id_field = parquet_schema_element_new("id", PARQUET_TYPE_INT32, 0, FALSE);
    schema_fields = g_list_append(schema_fields, id_field);
    
    // 创建UTF8字符串类型的"name"字段
    ParquetSchemaElement *name_field = parquet_schema_element_new("name", PARQUET_TYPE_BYTE_ARRAY, 0, FALSE);
    parquet_schema_element_set_converted_type(name_field, PARQUET_CONVERTED_TYPE_UTF8);
    schema_fields = g_list_append(schema_fields, name_field);
    
    ParquetSchema *schema = parquet_schema_new(schema_fields);
    g_list_free(schema_fields); // 字段列表用完可以释放

    // 第二步:配置写入器属性(比如压缩方式)
    ParquetFileWriterProperties *writer_props = parquet_file_writer_properties_new();
    parquet_file_writer_properties_set_compression(writer_props, PARQUET_COMPRESSION_SNAPPY);

    // 第三步:创建文件写入器
    ParquetFileWriter *file_writer = parquet_file_writer_new("demo_output.parquet", schema, writer_props);
    // 用完的资源及时释放
    parquet_schema_unref(schema);
    parquet_file_writer_properties_unref(writer_props);

    // 第四步:创建行组写入器(这里预分配2行数据)
    ParquetRowGroupWriter *row_group = parquet_file_writer_append_row_group(file_writer, 2);

    // 写入id列数据
    GArray *id_values = g_array_new(FALSE, FALSE, sizeof(gint32));
    gint32 ids[] = {1, 2};
    g_array_append_vals(id_values, ids, 2);
    ParquetColumnWriter *id_col_writer = parquet_row_group_writer_next_column(row_group);
    parquet_column_writer_write_batch(id_col_writer, 2, NULL, NULL, id_values->data, NULL);
    g_array_unref(id_values);
    parquet_column_writer_unref(id_col_writer);

    // 写入name列数据
    GArray *name_values = g_array_new(FALSE, FALSE, sizeof(GByteArray*));
    GByteArray *name_alice = g_byte_array_new();
    g_byte_array_append(name_alice, (guint8*)"Alice", 5);
    GByteArray *name_bob = g_byte_array_new();
    g_byte_array_append(name_bob, (guint8*)"Bob", 3);
    GByteArray *names[] = {name_alice, name_bob};
    g_array_append_vals(name_values, names, 2);
    ParquetColumnWriter *name_col_writer = parquet_row_group_writer_next_column(row_group);
    parquet_column_writer_write_batch(name_col_writer, 2, NULL, NULL, name_values->data, NULL);
    // 逐个释放字符串的字节数组
    for (guint i = 0; i < name_values->len; i++) {
        g_byte_array_free(g_array_index(name_values, GByteArray*, i), TRUE);
    }
    g_array_unref(name_values);
    parquet_column_writer_unref(name_col_writer);

    // 完成行组写入并释放资源
    parquet_row_group_writer_close(row_group);
    parquet_row_group_writer_unref(row_group);

    // 关闭文件写入器并释放
    parquet_file_writer_close(file_writer);
    parquet_file_writer_unref(file_writer);

    return 0;
}

完整读取Parquet文件的示例

这个示例会读取上面生成的Parquet文件,打印出所有行的数据:

#include <parquet-glib/parquet-glib.h>

int main() {
    g_type_init();

    // 打开Parquet文件
    ParquetFileReader *file_reader = parquet_file_reader_new("demo_output.parquet");
    ParquetSchema *schema = parquet_file_reader_get_schema(file_reader);
    
    // 打印Schema信息(可选,方便调试)
    g_print("文件Schema: %s\n", parquet_schema_to_string(schema));

    // 获取文件中的行组数量
    gint row_group_count = parquet_file_reader_get_num_row_groups(file_reader);
    for (gint i = 0; i < row_group_count; i++) {
        ParquetRowGroupReader *row_group = parquet_file_reader_get_row_group(file_reader, i);
        gint row_count = parquet_row_group_reader_get_num_rows(row_group);
        g_print("\n第%d个行组,共%d行数据:\n", i, row_count);

        // 读取id列
        ParquetColumnReader *id_col_reader = parquet_row_group_reader_next_column(row_group);
        GArray *id_values = g_array_new(FALSE, FALSE, sizeof(gint32));
        g_array_set_size(id_values, row_count);
        parquet_column_reader_read_batch(id_col_reader, row_count, NULL, NULL, id_values->data, NULL);
        g_print("ID列数据: ");
        for (guint j = 0; j < id_values->len; j++) {
            g_print("%d ", g_array_index(id_values, gint32, j));
        }
        g_print("\n");
        g_array_unref(id_values);
        parquet_column_reader_unref(id_col_reader);

        // 读取name列
        ParquetColumnReader *name_col_reader = parquet_row_group_reader_next_column(row_group);
        GArray *name_values = g_array_new(FALSE, FALSE, sizeof(GByteArray*));
        g_array_set_size(name_values, row_count);
        parquet_column_reader_read_batch(name_col_reader, row_count, NULL, NULL, name_values->data, NULL);
        g_print("Name列数据: ");
        for (guint j = 0; j < name_values->len; j++) {
            GByteArray *name = g_array_index(name_values, GByteArray*, j);
            g_print("%s ", (gchar*)name->data);
            g_byte_array_free(name, TRUE); // 释放每个字符串的字节数组
        }
        g_print("\n");
        g_array_unref(name_values);
        parquet_column_reader_unref(name_col_reader);

        parquet_row_group_reader_unref(row_group);
    }

    // 释放剩余资源
    parquet_schema_unref(schema);
    parquet_file_reader_close(file_reader);
    parquet_file_reader_unref(file_reader);

    return 0;
}

几个关键注意事项

  • 资源管理:parquet-glib的所有对象(比如ParquetSchema、ParquetFileWriter)都需要调用对应的unref函数手动释放,避免内存泄漏。如果用GLib 2.36及以上版本,也可以用g_autoptr宏来自动管理资源,减少手动unref的工作量。
  • Schema定义:如果需要处理嵌套结构、数组等复杂类型,只需要嵌套创建ParquetSchemaElement即可,核心逻辑和简单类型一致,只是字段的层级关系需要对应好。
  • 错误处理:上面的示例为了简洁省略了错误检查,实际开发中可以用g_error或者检查函数返回值来处理可能的错误(比如文件打开失败、写入失败等)。

备注:内容来源于stack exchange,提问作者CptPicard

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.16 10:48:14