如何为DatumWriter设置“字符集”||将包含阿拉伯字符的avro写入HDFS

0g0grzrc  于 2022-12-09  发布在  HDFS
关注(0)|答案(1)|浏览(205)

有些数据包含阿拉伯格式的值,当写入数据时,读卡器代码/hadoop fs -text命令显示??而不是阿拉伯字符。

1)编写器

// avro object is provided as SpecificRecordBase
Path path = new Path(pathStr);
DatumWriter<SpecificRecord> datumWriter = new SpecificDatumWriter<>();
FileSystem fs = FileSystem.get(URI.create(hdfsUri), conf); // HDFS File System

FSDataOutputStream outputStream = fs.create(path);
DataFileWriter<SpecificRecord> dataFileWriter = new DataFileWriter<>(datumWriter);

Schema schema = getSchema(); // method to get schema
dataFileWriter.setCodec(CodecFactory.snappyCodec());
dataFileWriter.create(schema, outputStream);
dataFileWriter.append(avroObject);

2)读取器

Configuration conf = new Configuration();
FsInput in = new FsInput(new Path(hdfsFilePathStr), conf);
DatumReader<Row> datumReader = new GenericDatumReader<>();
DataFileReader<Row> dataFileReader = new DataFileReader<>(in, datumReader);
GenericRecord outputData = (GenericRecord) dataFileReader.iterator.next();

我已经尝试了hadoop fs -text {filePath}命令,也有阿拉伯语的值显示为??.
更改数据写入的格式确实很困难,因为同一文件有许多使用者。
已尝试阅读SpecificRecordBase,但仍获得??.

编辑

也尝试过这些(在读者和作家):

Configuration conf = new Configuration();
conf.set("file.encoding", StandardCharsets.UTF_16.displayName());

以及

System.setProperty("file.encoding", StandardCharsets.UTF_16.displayName());

没用的。

u7up0aaq

u7up0aaq1#

显然,HDFS不支持很多非英语字符。要解决这个问题,请在avro模式中将字段从String更改为bytes
要将值从String转换为bytes,请用途:
ByteBuffer.wrap(str.getBytes(StandardCharsets.UTF_8)) .
然后,在阅读时,要将其转换回String,请用途:
new String(byteData.array(), StandardCharsets.UTF_8) .
读取器和写入器中的其余代码保持不变。
这样做,对于英语字符,hadooop fs -text命令将显示正确的文本,但对于非英语字符,它可能会显示乱码,但您的读者仍然能够从ByteBuffer创建UTF-8字符串。

相关问题