Java环境未安装Hadoop.dll与Winutils时能否实现JSON转Parquet
无外部环境依赖实现JSON数组转Parquet方案
别再用绑定Hadoop的旧版实现了,下面的方案全平台可运行,不需要装Hadoop、不需要配Winutils、不需要设置任何系统环境变量,打包后直接跑。
核心选型逻辑
之前大多数方案依赖Hadoop组件,本质是用了parquet-hadoop这个适配层,它强依赖Hadoop的文件系统抽象、配置加载逻辑,才会引出一堆环境问题。只要绕开这个模块,直接用Parquet核心序列化能力对接本地文件系统,就能完全去掉外部依赖:
- 仅保留Parquet核心的编码、列存结构处理逻辑,彻底排除所有Hadoop相关传递依赖
- 直接对接本地文件IO,不经过HDFS抽象层
- 生成的文件完全符合Parquet官方格式标准,和Hadoop生态产出的文件完全兼容
分语言实现
Java/Scala 实现
首先依赖只引入核心模块,全部排除Hadoop相关包:
<dependencies> <!-- Parquet核心包,排除所有Hadoop传递依赖 --> <dependency> <groupId>org.apache.parquet</groupId> <artifactId>parquet-column</artifactId> <version>1.14.2</version> <exclusions> <exclusion> <groupId>org.apache.hadoop</groupId> <artifactId>*</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.apache.parquet</groupId> <artifactId>parquet-encoding</artifactId> <version>1.14.2</version> <exclusions> <exclusion> <groupId>org.apache.hadoop</groupId> <artifactId>*</artifactId> </exclusion> </exclusions> </dependency> <!-- JSON解析用Jackson,无额外依赖 --> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.15.3</version> </dependency> </dependencies>
核心转换函数,直接用Parquet 1.13+版本自带的LocalOutputFile对接本地文件,完全不碰Hadoop API:
import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import org.apache.parquet.column.ParquetProperties; import org.apache.parquet.example.data.Group; import org.apache.parquet.example.data.simple.SimpleGroupFactory; import org.apache.parquet.hadoop.example.GroupWriteSupport; import org.apache.parquet.io.LocalOutputFile; import org.apache.parquet.schema.MessageType; import java.io.File; import java.io.IOException; public class JsonToParquetConverter { private static final ObjectMapper MAPPER = new ObjectMapper(); public static void convert(String jsonArrayContent, String outputParquetPath) throws IOException { JsonNode jsonArr = MAPPER.readTree(jsonArrayContent); if (!jsonArr.isArray()) throw new IllegalArgumentException("输入必须是JSON数组"); // 从JSON数据自动推导Parquet Schema,支持嵌套结构、数组类型 MessageType schema = SchemaParser.parseFromJsonArray(jsonArr); SimpleGroupFactory groupFactory = new SimpleGroupFactory(schema); // 直接对接本地文件输出,无Hadoop文件系统调用 LocalOutputFile outputFile = new LocalOutputFile(new File(outputParquetPath).toPath()); try (var writer = org.apache.parquet.hadoop.ParquetWriter.builder(outputFile) .withType(schema) .withWriteSupport(new GroupWriteSupport()) .withCompressionCodec(org.apache.parquet.hadoop.metadata.CompressionCodecName.SNAPPY) .withWriterVersion(ParquetProperties.WriterVersion.PARQUET_2_0) .build()) { for (JsonNode row : jsonArr) { Group group = groupFactory.newGroup(); RowWriter.writeJsonToGroup(row, group, schema); writer.write(group); } } } }
代码里SchemaParser和RowWriter两个辅助类逻辑很简单,就是做JSON类型到Parquet类型的映射:遍历JSON数组的字段,把字符串映射成binary、整数映射成int32/int64、浮点数映射成float/double、布尔映射成boolean、嵌套对象递归生成Group类型、数组映射成List类型即可。
Python 实现
Python端更简单,直接用最新版PyArrow,本身就没有Hadoop依赖,很多人以为要装Hadoop是被早期旧版的错误教程误导了:
import json import pyarrow as pa import pyarrow.parquet as pq def json_array_to_parquet(json_array_str: str, output_path: str) -> None: # 直接加载JSON数组转Arrow表,写Parquet全程无外部依赖 data = json.loads(json_array_str) table = pa.Table.from_pylist(data) pq.write_table(table, output_path, compression="snappy")
Windows环境下直接执行pip install pyarrow就能跑,完全不需要Winutils。
避坑点
- 坚决不要引入
parquet-hadoop依赖,所有Parquet依赖必须排查传递依赖,把org.apache.hadoop下的所有包全部排除,否则还是会触发Hadoop配置加载逻辑 - Parquet版本不要用1.12及更早的版本,这些版本没有自带本地文件适配类,需要自己实现
OutputFile接口,没必要浪费时间 - 压缩算法选SNAPPY、ZSTD这类纯Java/纯C实现的内置编解码器,不要选LZO这类需要额外安装本地库的格式,避免破坏可移植性
- 生成的Parquet文件可以直接被Spark、DuckDB、Pandas、ClickHouse等所有支持Parquet的组件读取,和Hadoop生态生成的文件没有任何区别
内容的提问来源于stack exchange,提问作者speci5
相关产品推荐
相关产品推荐

