java - java.io.IOException:从文件读取 Avro 时不是数据文件
问题描述
以下代码用于序列化数据。
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
BinaryEncoder binaryEncoder =
EncoderFactory.get().binaryEncoder(byteArrayOutputStream, null);
DatumWriter<GenericRecord> datumWriter = new GenericDatumWriter<>(data.getSchema());
datumWriter.setSchema(data.getSchema());
datumWriter.write(data, binaryEncoder);
binaryEncoder.flush();
byteArrayOutputStream.close();
result = byteArrayOutputStream.toByteArray();
我使用了以下命令
FileUtils.writeByteArrayToFile(new File("D:/sample.avro"), data);
将 avro 字节数组写入文件。但是当我尝试阅读相同的内容时
File file = new File("D:/sample.avro");
try {
dataFileReader = new DataFileReader(file, datumReader);
} catch (IOException exp) {
System.out.println(exp);
System.exit(1);
}
它抛出异常
java.io.IOException: Not a data file.
at org.apache.avro.file.DataFileStream.initialize(DataFileStream.java:105)
at org.apache.avro.file.DataFileReader.<init>(DataFileReader.java:97)
at org.apache.avro.file.DataFileReader.<init>(DataFileReader.java:89)
这里发生了什么问题。我提到了另外两个类似的stackoverflow问题this和this,但对我没有太大帮助。有人可以帮我理解这一点。
解决方案
实际数据以 Avro 二进制格式编码,但通常传递的不仅仅是编码数据。
大多数人对“avro 文件”的看法是一种格式,其中包括标题(其中包含诸如 writer 架构之类的内容)以及实际数据:https ://avro.apache.org/docs/current/spec.html#对象+容器+文件。avro 文件的前四个字节应该是 b"Obj1" 或 0x4F626A01。您收到的错误是因为您尝试作为数据文件读取的二进制文件不是以标准魔术字节开头。
另一种标准格式是单对象编码:https ://avro.apache.org/docs/current/spec.html#single_object_encoding 。这种类型的二进制格式应该以 0xC301 开头。
但如果我不得不猜测,您拥有的二进制文件可能只是没有任何类型的标头信息的原始序列化数据。尽管如果不知道您拥有的字节数组是如何创建的,则很难确定。
推荐阅读
- normal-distribution - 无法正确计算 np.cov()
- postgresql-9.5 - 尝试将视图从 oracle 转换为 PostgreSQL,出现错误关系“sys.dba_data_files”不存在
- docker - docker.sock 绑定挂载 AWS ECS Fargate
- bash - Shell、IFS、读取和制表
- python - sympy - 积分的奇怪行为。解决方案中包含大量数字的数字
- angular - 在角度 11 中安装 ng-bootstrap 时出错
- python - 如何在 GPU 上运行 datawig?
- javascript - 如何将服务器端 JSON 传递/导入到 vue 应用程序?
- python - HTML 到 PDF 还保留了 Django 中的 CSS 和引导样式
- php - Codeigniter 3 验证码助手 create_captcha 返回 bool