我有一个镶木地板文件,其中包含来自RDBMS表的归档数据(因此所有值的重复级别基本为0)。我需要一次读取一列文件。基本上这是我想要执行的序列: 读取镶木地板文件中的表格列中的所有值 - >将其写入TEXT文件 - >读取镶木地板文件中下一个表格列的所有值 - >把它写到另一个TEXT文件....依此类推。
在java中执行此操作的最有效方法是什么?
PS:我首先选择了镶木地板(而不是avro)进行存档,因为与avro相比,镶木地板可以帮助我实现更好的压缩效果。此外,由于我的要求是一次读取列的所有值,我的假设是,考虑到格式的固有特性(柱状存储),使用镶木地板会更快。[编辑] 这是我用来逐列读取RDBMS表的代码。为简单起见,假设表中的所有列都包含String(Varchar)值:
public static void main(String[] args) throws IllegalArgumentException {
Configuration conf = new Configuration();
try {
ParquetMetadata readFooter = ParquetFileReader.readFooter(conf, path, ParquetMetadataConverter.NO_FILTER);
MessageType schema = readFooter.getFileMetaData().getSchema();
ParquetFileReader r = new ParquetFileReader(conf, path, readFooter);
PageReadStore rowGroup = null;
try {
while (null != (rowGroup = r.readNextRowGroup())) {
numRowGroups++;
rows+= rowGroup.getRowCount();
ColumnReader colReader = null;
ColumnReadStore colReadStore = new ColumnReadStoreImpl(rowGroup,new GroupRecordConverter(schema).getRootConverter(), schema, "blah");
List<ColumnDescriptor> descriptorList = schema.getColumns();
//for each column
for(ColumnDescriptor colDescriptor:descriptorList) {
//Get datatype of the column
PrimitiveTypeName type = colDescriptor.getType();
String[] columnNamePath = colDescriptor.getPath();
columnName =Arrays.toString(columnNamePath);
colReader = colReadStore.getColumnReader(colDescriptor);
long totalValuesInColumnChunk = rowGroup.getPageReader(colDescriptor).getTotalValueCount();
//For every cell in the column chunk
for (int i = 0; i < totalValuesInColumnChunk; i++) {
System.out.println(columnName+" "+colReader.getBinary().toStringUsingUTF8());
colReader.consume();
}
}
}
}
catch(Exception ex){
ex.printStackTrace();
}
finally {
r.close();
}
} catch (IOException e) {
System.out.println("Error reading parquet file.");
e.printStackTrace();
}
System.out.println("Total number of rows: "+rows);
}