Hive 高级操作(五)之 HIVE 特殊分隔符处理
1、hive 读取数据的机制
hive 读取数据的机制:
(1)首先用 InputFormat <默认是:org.apache.hadoop.mapred.TextInputFormat > 的一个具体实现类读入文件数据,返回一条一条的记录(可以是行,或者是你逻辑中的“行”)。
(2)然后利用 SerDe <默认:org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe> 的一个具体实现类,对上面返回的一条一条的记录进行字段切割。
Hive 对文件中字段的分隔符默认情况下只支持单字节分隔符,如果数据文件中的分隔符是多字符的,如下所示(“||”):
01||huangbo
02||xuzheng
03||wangbaoqiang
2、使用 RegexSerDe 通过正则表达式来抽取字段
(1)创建一个存储信息的表,使用正则表达式来指定分隔符:
create table t_bi_reg(
id string,
name string
)
row format serde 'org.apache.hadoop.hive.serde2.RegexSerDe'
with serdeproperties('input.regex'='(.*)\\|\\|(.*)','output.format.string'='%1$s %2$s')
stored as textfile;
(2)加载数据到表 t_bi_reg:
hive>load data local inpath '/home/hadoop/hivedata/bi.dat' into table t_bi_reg;
(3)查询表中数据信息是否加载正确:
hive>select * from t_bi_reg;
3、通过自定义 InputFormat 解决特殊分隔符问题
其原理是在 inputformat 读取行的时候将数据中的 “多字节分隔符” 替换为 hive 默认的分隔符(ctrl+A 亦即 \001)或用于替代的单字符分隔符,以便 hive 在 serde 操作时按照默认的单字节分隔符进行字段抽取。
com.zc.hive.BiDelimiterInputFormat:
package com.zc.hive;
import java.io.IOException;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapred.FileSplit;
import org.apache.hadoop.mapred.InputSplit;
import org.apache.hadoop.mapred.JobConf;
import org.apache.hadoop.mapred.RecordReader;
import org.apache.hadoop.mapred.Reporter;
import org.apache.hadoop.mapred.TextInputFormat;
/**
* @作者: zc
* @时间: 2021/3/9 15:46
* @描述: 自定义 InputFormat 解决特殊分隔符问题
*/
public class BiDelimiterInputFormat extends TextInputFormat {
@Override
public RecordReader<LongWritable, Text> getRecordReader(InputSplit genericSplit,
JobConf job,
Reporter reporter)
throws IOException {
reporter.setStatus(genericSplit.toString());
BiRecordReader reader = new BiRecordReader(job,(FileSplit)genericSplit);
// MyRecordReader reader = new MyRecordReader(job,(FileSplit)genericSplit);
return reader;
}
}
com.zc.hive.BiRecordReader:
package com.zc.hive;
import java.io.IOException;
import java.io.InputStream;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FSDataInputStream;
import org.apache.hadoop.fs.FileSystem;
import org.apache