千家信息网

hive中对多字节的处理

发表于:2026-11-01 作者:千家信息网编辑
千家信息网最后更新 2026年11月01日,现在有一批数据:01||zs||1802||ls||1903||jj||10每一行的数据的分割符是||,是一个多字节的分隔符,默认的hive只支持单字节的分隔符,上面的数据时||多字节,不支持。解决方
千家信息网最后更新 2026年11月01日hive中对多字节的处理

现在有一批数据:

01||zs||1802||ls||1903||jj||10

每一行的数据的分割符是||,是一个多字节的分隔符,默认的hive只支持单字节的分隔符,上面的数据时||多字节,不支持。
解决方案:
 method01:使用 RegexSerDe 通过正则表达式来抽取字段

#建表语句create table t_bi_reg(id string,name string,age string ) row format serde 'org.apache.hadoop.hive.serde2.RegexSerDe'  with serdeproperties('input.regex'='((.\*)\\\\|\\\\|(.\*)\\\\|\\\\|(.\*))','output.format.string'='%1$s %2$s %3s')#input.regex:指定切分的正则#output.format.string:切分之后输出的字段#加载数据load data local inpath '/Hadoop/data/1.txt' into table t_bi_reg#查询select * from t_bi_reg;


  method2:修改源码:
 原理是在 inputformat 读取行的时候将数据中的"多字节分隔符"替换为 hive 默认的分隔 符(ctrl+A 亦即 \001)或用于替代的单字符分隔符,以便 hive 在 serde 操作时按照默认的 单字节分隔符进行字段抽取。
代码
com.zy.hive.delimit2.BiDelimiterInputFormat:

package com.zy.hive.delimit2;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;public class BiDelimiterInputFormat extends TextInputFormat {@Overridepublic RecordReader 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.zy.hive.delimit2.BiRecordReader

package com.zy.hive.delimit2;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.hadoop.fs.Path;import org.apache.hadoop.fs.Seekable;import org.apache.hadoop.io.LongWritable;import org.apache.hadoop.io.Text;import org.apache.hadoop.io.compress.CodecPool;import org.apache.hadoop.io.compress.CompressionCodec;import org.apache.hadoop.io.compress.CompressionCodecFactory;import org.apache.hadoop.io.compress.Decompressor;import org.apache.hadoop.io.compress.SplitCompressionInputStream;import org.apache.hadoop.io.compress.SplittableCompressionCodec;import org.apache.hadoop.mapred.FileSplit;import org.apache.hadoop.mapred.LineRecordReader;import org.apache.hadoop.mapred.RecordReader;public class BiRecordReader implements RecordReader {private static final Log LOG = LogFactory.getLog(LineRecordReader.class.getName());private CompressionCodecFactory compressionCodecs = null;private long start;private long pos;private long end;private LineReader in;int maxLineLength;private Seekable filePosition;private CompressionCodec codec;private Decompressor decompressor;/*** A class that provides a line reader from an input stream.* @deprecated Use {@link org.apache.hadoop.util.LineReader} instead.*/@Deprecatedpublic static class LineReader extends org.apache.hadoop.util.LineReader {LineReader(InputStream in) {super(in);}LineReader(InputStream in, int bufferSize) {super(in, bufferSize);}public LineReader(InputStream in, Configuration conf)throws IOException {Stay hungry Stay foolish -- http://blog.csdn.net/zhongqi2513super(in, conf);}}public BiRecordReader(Configuration job, FileSplit split) throws IOException {this.maxLineLength = job.getInt("mapred.linerecordreader.maxlength",Integer.MAX_VALUE);start = split.getStart();end = start + split.getLength();final Path file = split.getPath();compressionCodecs = new CompressionCodecFactory(job);codec = compressionCodecs.getCodec(file);// open the file and seek to the start of the splitFileSystem fs = file.getFileSystem(job);FSDataInputStream fileIn = fs.open(split.getPath());if (isCompressedInput()) {decompressor = CodecPool.getDecompressor(codec);if (codec instanceof SplittableCompressionCodec) {final SplitCompressionInputStream cIn = ((SplittableCompressionCodec) codec).createInputStream(fileIn, decompressor, start, end,SplittableCompressionCodec.READ_MODE.BYBLOCK);in = new LineReader(cIn, job);start = cIn.getAdjustedStart();end = cIn.getAdjustedEnd();filePosition = cIn; // take pos from compressed stream} else {in = new LineReader(codec.createInputStream(fileIn,decompressor), job);filePosition = fileIn;}} else {fileIn.seek(start);in = new LineReader(fileIn, job);filePosition = fileIn;}// If this is not the first split, we always throw away first record// because we always (except the last split) read one extra line in// next() method.if (start != 0) {start += in.readLine(new Text(), 0, maxBytesToConsume(start));}this.pos = start;Stay hungry Stay foolish -- http://blog.csdn.net/zhongqi2513}private boolean isCompressedInput() {return (codec != null);}private int maxBytesToConsume(long pos) {return isCompressedInput() ? Integer.MAX_VALUE : (int) Math.min(Integer.MAX_VALUE, end - pos);}private long getFilePosition() throws IOException {long retVal;if (isCompressedInput() && null != filePosition) {retVal = filePosition.getPos();} else {retVal = pos;}return retVal;}public BiRecordReader(InputStream in, long offset, long endOffset,int maxLineLength) {this.maxLineLength = maxLineLength;this.in = new LineReader(in);this.start = offset;this.pos = offset;this.end = endOffset;this.filePosition = null;}public BiRecordReader(InputStream in, long offset, long endOffset,Configuration job) throws IOException {this.maxLineLength = job.getInt("mapred.linerecordreader.maxlength",Integer.MAX_VALUE);this.in = new LineReader(in, job);this.start = offset;this.pos = offset;this.end = endOffset;this.filePosition = null;}public LongWritable createKey() {return new LongWritable();Stay hungry Stay foolish -- http://blog.csdn.net/zhongqi2513}public Text createValue() {return new Text();}/** Read a line. */public synchronized boolean next(LongWritable key, Text value)throws IOException {// We always read one extra line, which lies outside the upper// split limit i.e. (end - 1)while (getFilePosition() <= end) {key.set(pos);int newSize = in.readLine(value,maxLineLength,Math.max(maxBytesToConsume(pos), maxLineLength));String str = value.toString().replaceAll("\\|\\|", "\\|");value.set(str);pos += newSize;if (newSize == 0) {return false;}if (newSize < maxLineLength) {return true;}// line too long. try againLOG.info("Skipped line of size " + newSize + " at pos "+ (pos - newSize));}return false;}/*** Get the progress within the split*/public float getProgress() throws IOException {if (start == end) {return 0.0f;} else {return Math.min(1.0f, (getFilePosition() - start)Stay hungry Stay foolish -- http://blog.csdn.net/zhongqi2513/ (float) (end - start));}}public synchronized long getPos() throws IOException {return pos;}public synchronized void close() throws IOException {try {if (in != null) {in.close();}} finally {if (decompressor != null) {CodecPool.returnDecompressor(decompressor);}}}}

注意:上述代码中的 api 全部使用 hadoop 的老 api 接口 org.apache.hadoop.mapred". 然后将工程打包,并拷贝至 hive 安装目录的 lib 文件夹中,并重启 hive,使用以下语句建表 即可
具体步骤:
hive> add jar /home/hadoop/apps/hive/lib/myinput.jar #将jar包导入hive的classpath中
hive> create table new_bi(id string,name string) #建表

row format delimited
fields terminated by '|'
stored as inputformat 'com.zy.hive.delimit2.BiDelimiterInputFormat' outputformat
outputformat
'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat';
hive> load data local inpath '/Hadoop/data/1.txt' into table t_bi_reg #导入数据
hive>select * from t_bi_reg #查询

数据 字节 分隔符 字段 代码 正则 语句 抽取 支持 查询 一行 单字 原理 工程 拷贝 接口 文件 文件夹 方案 时候 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 互联网科技企业 今日互联网科技 深圳互联网科技公司 华中科技大学互联网 唐信互联网科技 大连 米客互联网科技 金融科技和互联网金融 广西拼得多互联网科技有限公司 安控科技rtu产品工业互联网 贵州叶脉互联网科技有限公司所属行业 互联网金融科技名词解释 上海京穆互联网科技有限公司 广州富喜互联网络科技 21世纪互联网科技成就 互联网科技融合创新 有人说阿里系是互联网科技企业 互联网金融运营模式中的金融科技 河南商务圈互联网科技有限公司 科技互联网专业务虚会材料 网互联网络科技 广东万易互联网科技有限公司惠州分公司 云之行互联网科技 江苏根荣互联网科技 中资互联网科技 百单互联网科技有限公司 中国最先进互联网科技公司 温州喔噻互联网科技有限公司 中天科技中国工业互联网 本届互联网大会上的黑科技 科技发展第三阶段互联网时代
0