我想使用Apache Avro来序列化我的数据,我的客户端是用C++编写的,而我的服务器是用Java编写的.
我的服务器java代码如下所示:
Schema scm = new Schema.Parser().parse("....shcema String.....");
ByteArrayInputStream inputStream = new ByteArrayInputStream(record.array());
Decoder coder = new DecoderFactory().directBinaryDecoder(inputStream, null);
GenericDatumReader<GenericRecord> reDatumReader = new GenericDatumReader<GenericRecord>(scm);
try {
GenericRecord result = (GenericRecord)reDatumReader.read(null, coder);
//here! the result "name", "num_groups" is empty!
System.out.println(result.get("name")+" "+result.get("num_groups"));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Run Code Online (Sandbox Code Playgroud)我的客户代码:
std::string schemaDescript ="....shcema String.....";
std::stringstream rsStream(schemaDescript);
avro::ValidSchema rSchema;
avro::compileJsonSchema(rsStream, rSchema);
avro::EncoderPtr encoder = avro::binaryEncoder();
std::auto_ptr<avro::OutputStream> oStream = avro::memoryOutputStream();
encoder->init(*oStream);
avro::GenericDatum rData(rSchema);
avro::GenericRecord sReord = rData.value<avro::GenericRecord>();
sReord.setFieldAt(0, avro::GenericDatum("i am nice"));
sReord.setFieldAt(1, avro::GenericDatum(1));
sReord.setFieldAt(2, avro::GenericDatum(12));
sReord.setFieldAt(3, avro::GenericDatum(13));
avro::GenericWriter gwriter(rSchema, encoder);
gwriter.write(rData);
oStream->flush();
std::auto_ptr<avro::InputStream> inSt = avro::memoryInputStream(*oStream);
avro::StreamReader instReader(*inSt);
size_t outputLen = oStream->byteCount();
uint8_t* theByteData = new uint8_t[outputLen];
instReader.hasMore();
instReader.readBytes(theByteData, outputLen);
Run Code Online (Sandbox Code Playgroud)我发送theByteData到服务器,代码工作(没有例外),但结果是空的,谁能告诉我什么是错的?
为什么在Java中,我们得到与键值:result.get("name"); 但是在C++中我们用索引获得价值:record.fieldAt(0).value<string>().如果我无法使用字符串键获取值,如何将索引与字符串键匹配?
小智 1
今天早上我遇到了同样的问题,我在 Avro Test Cpp 文件(“DataFileTests.cc”)中使用“testWriteGeneric”函数找到了解决方案。
例如:
我的架构文件(cpx.json):
{
"type": "record",
"name": "cpx",
"fields" : [
{"name": "re", "type": "double"},
{"name": "im", "type" : "int"}
]
}
Run Code Online (Sandbox Code Playgroud)
我的Cpp文件:
typedef std::pair<avro::ValidSchema, avro::GenericDatum> Pair;
int main(int ac, char **av)
{
// encode
std::ifstream ifs(cpx.json);
avro::ValidSchema schema;
avro::compileJsonSchema(ifs, schema);
// I create a pair of validSchema and GenericDatum
Pair p(schema, avro::GenericDatum());
avro::GenericDatum &Data = p.second;
Data = avro::GenericDatum(schema);
avro::GenericRecord &sReord = Data.value<avro::GenericRecord>();
// I set my values
sReord.setFieldAt(sReord.fieldIndex("re"), avro::GenericDatum(42.5));
sReord.setFieldAt(sReord.fieldIndex("im"), avro::GenericDatum(24));
// I create a DataFileWriter and i write my pair of ValidSchema and GenericValue
avro::DataFileWriter<Pair> dataFileWriter("test.bin", schema);
dataFileWriter.write(p);
dataFileWriter.close();
}
Run Code Online (Sandbox Code Playgroud)