我正试图将一个小rcfile(约200行数据)读入hashmap中,以进行map-side连接,但在将文件中的数据转换为可用状态时遇到了很多困难。
到目前为止,我掌握了以下内容,其中大部分是从这个例子中提取出来的:
public void configure(JobConf job)
{
try
{
FileSystem fs = FileSystem.get(job);
RCFile.Reader rcFileReader = new RCFile.Reader(fs, new Path("/path/to/file"), job);
int counter = 1;
while (rcFileReader.next(new LongWritable(counter)))
{
System.out.println("Fetching data for row " + counter);
BytesRefArrayWritable dataRead = new BytesRefArrayWritable();
rcFileReader.getCurrentRow(dataRead);
System.out.println("dataRead: " + dataRead + " dataRead.size(): " + dataRead.size());
for (int i = 0; i < dataRead.size(); i++)
{
BytesRefWritable bytesRefRead = dataRead.get(i);
byte b1[] = bytesRefRead.getData();
Text returnData = new Text(b1);
System.out.println("READ-DATA = " + returnData.toString());
}
counter++;
}
}
catch (IOException e)
{
throw new Error(e);
}
}
但是,我得到的输出在第一行中将每列中的所有数据连接在一起,而在其他任何行中都没有数据。
Fetching data for row 1
dataRead: org.apache.hadoop.hive.serde2.columnar.BytesRefArrayWritable@7f26d3df dataRead.size(): 5
READ-DATA = 191606656066860670
READ-DATA = United StatesAmerican SamoaGuamNorthern Mariana Islands
READ-DATA = USASGUMP
READ-DATA = USSouth PacificSouth PacificSouth Pacific
READ-DATA = 19888
Fetching data for row 2
dataRead: org.apache.hadoop.hive.serde2.columnar.BytesRefArrayWritable@1cb1a4e2 dataRead.size(): 0
Fetching data for row 3
dataRead: org.apache.hadoop.hive.serde2.columnar.BytesRefArrayWritable@52c00025 dataRead.size(): 0
Fetching data for row 4
dataRead: org.apache.hadoop.hive.serde2.columnar.BytesRefArrayWritable@3b49a794 dataRead.size(): 0
如何正确读入这些数据,以便一次只能访问一行 (191, United States, US, US, 19)
?
2条答案
按热度按时间30byixjq1#
由于rcfiles的列特性,行读路径与写路径有很大的不同。我们仍然可以使用rcfile.reader类按行读取rcfile(不需要rcfilerecordreader)。但除此之外,我们还需要使用columnarserde将列数据转换为行数据。
下面是我们可以得到的最简化的代码,用于逐行读取RCF文件。有关详细信息,请参阅内联代码注解。
在这段代码中,getcourrentrow仍然按列读取数据,我们需要使用serde将其转换为行。还有,打电话
getCurrentRow()
并不意味着行中的所有字段都已解压缩。实际上,根据lazy decompression,一个列在它的一个字段被反序列化之前不会被解压缩。为此,我们使用了coulmnarStruct.getFieldsAsList()
获取对惰性对象的引用列表。实际读数发生在getWritableObject()
调用lazystring引用。实现同样目标的另一种方法是
StructObjectInspector
使用copyToStandardObject
应用程序编程接口。但我发现上面的方法更简单。jgzswidk2#
经过进一步的挖掘,我找到了解决办法。关键是不要使用
RCFile.Reader
但是使用RCFileRecordReader
.以下是我最终得到的结果,也适用于打开多个文件:
和allcountryesrow.valueof:
(注意
Column
列的枚举,按列在每行和中的显示顺序排列serDe
是的示例ColumnarSerDe
)最后得到一个allcountriesrow对象,其中包含相关行的所有信息。