我必须编写一个map reduce批处理(使用org.apache.hadoop.mapreduce.*
API)来处理具有以下属性的文本文件:
- iso - 8859 - 1编码。 像<<li> CSV/gh>
- 分离器为
0xef
我使用TextInputFormat
,因为我想自己执行字段分割。然而,TextInputFormat
似乎只能处理UTF-8编码的文件。
根据MAPREDUCE-232,自2008年以来有一个待解决的补丁,但我还没有找到一个解决方案。我有什么选择?不能预先将文件转换为UTF-8格式。
编辑:在阅读Hadoop源代码时,我想出了一个可能的解决方案。LineReader
,朋友只处理字节。它们从不将字节转换为String,它们只匹配硬编码的行末分隔符并填充字节缓冲区。由于ISO_8859_1和UTF-8对n
共享相同的字节序列,因此可以使用:
public class MyMapper extends Mapper<IntWritable, Text, Text, Text> {
public void map(IntWritable key, Text value, Context context)
throws IOException, InterruptedException {
String data = new String(value.getBytes(),
0, value.getLength(),
Charsets.ISO_8859_1)
// [...]
}
}
这个解决方案可以接受吗?
我对TextInputFormat没有任何特别的经验,但如果您所说的是真的(底层代码只查找n
的单个字节值),那么使用示例代码将这些字节转换为字符串将是完全合法的。
您对依赖实现细节的担忧是正确的,然而,这里有一些对您有利的观点:
- "bug修复"自2008年以来仍然开放,并被拒绝,因为它没有正确处理所有编码(也就是说,这是一个需要更多工作来正确修复的难题)
-
Text
类显式地使用utf-8编码。很难在不破坏整个世界的情况下改变它。 - 在第2点之后,因为你的目标编码有一个与utf-8兼容的换行字节序列,只要你总能得到原始的原始字节,你应该没问题。