如何使用 Avro 生成 String 类型的字段而不是 CharSequence?
Posted
技术标签:
【中文标题】如何使用 Avro 生成 String 类型的字段而不是 CharSequence?【英文标题】:How to generate fields of type String instead of CharSequence using Avro? 【发布时间】:2014-09-26 22:18:36 【问题描述】:我编写了一个 Avro 模式,其中一些字段 ** 需要是 ** 类型为 String
但 Avro 生成了这些类型为 CharSequence
的字段。
我无法找到任何方法告诉 Avro 将这些字段设为 String
类型。
我尝试使用
"fields": [
"name":"startTime",
"type":"string",
"avro.java.stringImpl":"String"
,
"name":"endTime",
"type":"string",
"avro.java.string":"String"
]
但是对于这两个字段,Avro 正在生成 CharSequence
类型的字段。
还有其他方法可以使这些字段成为String
类型的字段吗?
【问题讨论】:
String
类实现CharSequence
接口。
CharSequence 是一个接口。默认情况下,Avro 使用自己的 Utf8 类作为 CharSequence 实现。 Utf8 不超过一个字节缓冲区,可以使用toString
转换为字符串。当您不关心基准测试中的字符串时,Utf8 很方便......但大多数情况下您要使用 CharSequence 并且必须将其转换为字符串。这很麻烦,而且会占用 100% 的内存开销,因为字符串现在既存储为 Utf8 又存储为字符串。这就是为什么很多人想要 String 而不是 CharSequence。将两者混合起来也很有用。
【参考方案1】:
如果您希望所有字符串字段都是java.lang.String
的实例,那么您只需配置编译器:
java -jar /path/to/avro-tools-1.7.7.jar compile -string schema
或者如果您使用的是 Maven 插件
<plugin>
<groupId>org.apache.avro</groupId>
<artifactId>avro-maven-plugin</artifactId>
<version>1.7.7</version>
<configuration>
<stringType>String</stringType>
</configuration>
[...]
</plugin>
如果您希望某个特定字段为 java.lang.String 类型,那么...您不能。编译器不支持它。您可以将“java-class”与反射 API 一起使用,但编译器并不关心。
如果您想了解更多信息,可以在 SpecificCompiler 第 372 行,Avro 1.7.7 中设置断点。您可以看到,在调用addStringType()
之前,架构在props
字段中有所需的信息。如果您将此模式传递给SpecificCompiler.javaType()
,那么它将执行您想要的操作。但是随后addStringType
将您的架构替换为静态架构。我很可能会在邮件列表上问这个问题,因为我没有明白这一点。
【讨论】:
有这方面的文档吗?我正在寻找如何指定数组类型。我希望它被设置而不是java.util.list
,但找不到任何文档:/
它也适用于 1.8.2。干杯@Clément MATHIEU【参考方案2】:
您可以按字段级别设置它,只需将类型更改为对象,并包括 "type" : "string" 和 "avro.java.string" : "String"
请看下面的例子:
"type": "record",
"name": "test",
"fields": [
"name": "name",
"type":
"type": "string",
"avro.java.string": "String"
]
【讨论】:
那行不通。我们以这种方式定义了 avro 文件,但我们仍然得到 CharSequence 而不是 String。使用 maven 配置的 Mathieu 解决方案在我们的案例中运行良好。以上是关于如何使用 Avro 生成 String 类型的字段而不是 CharSequence?的主要内容,如果未能解决你的问题,请参考以下文章