如何为 DatumWriter 设置 'charset' ||将包含阿拉伯字符的avro写入HDFS
How to set 'charset' for DatumWriter || write avro that contains arabic characters to HDFS
部分数据包含阿拉伯语格式的值,写入数据时,reader代码/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) Reader
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
,但仍在阅读 ??
。
编辑
还尝试了这些(在 reader 和 writer 中):
Configuration conf = new Configuration();
conf.set("file.encoding", StandardCharsets.UTF_16.displayName());
和
System.setProperty("file.encoding", StandardCharsets.UTF_16.displayName());
没有帮助。
显然,HDFS 不支持很多 non-english 字符。要解决此问题,请在您的 avro 模式中将字段从 String
更改为 bytes
。
要将您的值从 String
转换为 bytes
,请使用:
ByteBuffer.wrap(str.getBytes(StandardCharsets.UTF_8))
.
然后,在读取时,将其转换回字符串,使用:
new String(byteData.array(), StandardCharsets.UTF_8)
.
您 reader 和作者中的其余代码保持不变。
这样做,对于英文字符 hadooop fs -text
命令将显示正确的文本,但对于 non-English 字符它可能会显示乱码,但是您的 reader 仍然能够创建 UTF-8
来自 ByteBuffer
.
的字符串
部分数据包含阿拉伯语格式的值,写入数据时,reader代码/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) Reader
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
,但仍在阅读 ??
。
编辑
还尝试了这些(在 reader 和 writer 中):
Configuration conf = new Configuration();
conf.set("file.encoding", StandardCharsets.UTF_16.displayName());
和
System.setProperty("file.encoding", StandardCharsets.UTF_16.displayName());
没有帮助。
显然,HDFS 不支持很多 non-english 字符。要解决此问题,请在您的 avro 模式中将字段从 String
更改为 bytes
。
要将您的值从 String
转换为 bytes
,请使用:
ByteBuffer.wrap(str.getBytes(StandardCharsets.UTF_8))
.
然后,在读取时,将其转换回字符串,使用:
new String(byteData.array(), StandardCharsets.UTF_8)
.
您 reader 和作者中的其余代码保持不变。
这样做,对于英文字符 hadooop fs -text
命令将显示正确的文本,但对于 non-English 字符它可能会显示乱码,但是您的 reader 仍然能够创建 UTF-8
来自 ByteBuffer
.