Mapreduce中的字符串编码

$$$

Shuffle的执行过程,需要经过多次比较排序。如果对每一个数据的比较都需要先反序列化,对性能影响极大。 RawComparator的作用就不言而喻,能够直接使用序列化后的字节流进行比较,不需要反序列化就能够完成排序功能。

$$$

hadoop使用的是jdk自带编码器和解码器(DataOutputStream和DataInputStream),它有一套规则把字符转化成字节。1个字符可能转化成1个,2个或者3个字节。

字节流开始处用2个字节,写了字节流的有效长度,它的字节流最长是65535 (这个长度是编码后的字节流长度,不是传进行的字符串长度)

在RawComparator读到的,是在这种规则下转换后的字节流,不能够直接使用它来做比较了。。。在 二次排序 里面我用了一种变通的方法解决这个问题。最好的方法是模仿Text的编码和比较器的实现,然后实现自定义key的比较器

在这里主要是解析一下,Why???

DataOutputStream.writeUTF()的源码不长,直接上

    /**
** 把字符串编码为utf字节流,并写进out
**/
static int writeUTF(String str, DataOutput out) throws IOException {
int strlen = str.length();
int utflen = 0;
int c, count = 0; /* 计算编码后的字节流长度 */
for (int i = 0; i < strlen; i++) {
c = str.charAt(i);
if ((c >= 0x0001) && (c <= 0x007F)) { // ascii字符,1个字符->1个字节
utflen++;
} else if (c > 0x07FF) { // 1个字符->3个字节
utflen += 3;
} else {
utflen += 2; // 1个字符->2个字节
}
} // 编码后的字节流总长度不能超过65535
if (utflen > 65535)
throw new UTFDataFormatException(
"encoded string too long: " + utflen + " bytes"); // 初始化用于编码的缓冲区
byte[] bytearr = null;
if (out instanceof DataOutputStream) {
DataOutputStream dos = (DataOutputStream)out;
if(dos.bytearr == null || (dos.bytearr.length < (utflen+2)))
dos.bytearr = new byte[(utflen*2) + 2];
bytearr = dos.bytearr;
} else {
bytearr = new byte[utflen+2];
} // 开头的2个字节,写字符串长度 utflen
bytearr[count++] = (byte) ((utflen >>> 8) & 0xFF);
bytearr[count++] = (byte) ((utflen >>> 0) & 0xFF); // 先写入 [1到7E]的字符, 即ascii字符, 1个字符->1个字节
int i=0;
for (i=0; i<strlen; i++) {
c = str.charAt(i);
if (!((c >= 0x0001) && (c <= 0x007F))) break;
bytearr[count++] = (byte) c;
} for (;i < strlen; i++){
c = str.charAt(i);
if ((c >= 0x0001) && (c <= 0x007F)) { // ascii字符
bytearr[count++] = (byte) c; } else if (c > 0x07FF) { // 非ascii字符,需要3个字节
bytearr[count++] = (byte) (0xE0 | ((c >> 12) & 0x0F));
bytearr[count++] = (byte) (0x80 | ((c >> 6) & 0x3F));
bytearr[count++] = (byte) (0x80 | ((c >> 0) & 0x3F));
} else {
bytearr[count++] = (byte) (0xC0 | ((c >> 6) & 0x1F)); // 其余的非ascii字符,需要2个字节
bytearr[count++] = (byte) (0x80 | ((c >> 0) & 0x3F));
}
}
out.write(bytearr, 0, utflen+2);
return utflen + 2;
}

Mapreduce中的字符串编码的更多相关文章

  1. 使用自己的Python函数处理Protobuf中的字符串编码

    我目前所在的项目是一个老项目,里面的字符串编码有点乱,数据库中有些是GB2312,有些是UTF8:代码中有些是GBK,有些是UTF8,代码中转来转去,经常是不太清楚当前这个字符串是什么编码,由于是老项 ...

  2. 关于python中的字符串编码理解

    python2.x 中中间编码为unicode,一个字符串需要decode为unicode,再encode为其它编码格式(gbk.utf8等) 以gbk转utf8为例: s = "我是字符串 ...

  3. javascript中的字符串编码、字符串方法详解

    js中的字符串是一种类数组,采用UTF-16编码的Unicode字符集,意味字符串的每个字符可用下标方式获取,而每个字符串在内存中都是一个16位值组成的序列.js对字符串的各项操作均是在对16位值进行 ...

  4. Python2和Python3中的字符串编码问题解决

    Python2和Python3在字符串编码上是有明显的区别. 在Python2中,字符串无法完全地支持国际字符集和Unicode编码.为了解决这种限制,Python2对Unicode数据使用了单独的字 ...

  5. python中的字符串编码问题——1.理解编码和解码问题

    理解编码与解码(python2.7):1)编码 是根据一个想要的编码名称,把一个字符串翻译为其原始字节形式.>>> u_str=u'字符串编码aabbbcccddd'>> ...

  6. JavaScript中有对字符串编码的三个函数:escape,encodeURI,encodeURIComponent

    JavaScript中有三个可以对字符串编码的函数,分别是: escape,encodeURI,encodeURIComponent,相应3个解码函数:unescape,decodeURI,decod ...

  7. Python3中转换字符串编码

    在使用subprocess调用Windows命令时,遇到了字符串不显示中文的问题,源码如下:#-*-coding:utf-8-*-__author__ = '$USER' #-*-coding:utf ...

  8. Code::Blocks开发中的字符串编码错误

    刚开始使用Code::Blocks开发Windows中文应用程序的朋友们,如果在代码中使用了中文字符串,编译时可能遇到过Illegal byte sequence或Failure to convert ...

  9. python中的字符串编码问题——4.unicode编解码(以实际工作中遇到的韩文编码为例)

    韩文unicode编解码  问题是这样,工作中遇到有韩文数据出现乱码,说是unicode码. 类似这样: id name 323 52186863 149 63637538 314 65516863 ...

随机推荐

  1. 组合vs继承

    继承,建立子类. 组合(或聚集),在类定义中引用其它类的实例.

  2. SQL在指定列后添加新的列

    ALTER TABLE `MR_CustomerShopFuture` ADD COLUMN `ProcessID` INT(11) DEFAULT '0' COMMENT '审核流程ID';

  3. SparkSQL使用之Spark SQL CLI

    Spark SQL CLI描述 Spark SQL CLI的引入使得在SparkSQL中通过hive metastore就可以直接对hive进行查询更加方便:当前版本中还不能使用Spark SQL C ...

  4. 【转】SQL Server 2008下载 (附注册码)

    SQL Server 2008 中文试用版下载地址:http://sqlserver.dlservice.microsoft.com/dl/download/B/8/0/B808AF59-7619-4 ...

  5. leetcode 349:两个数组的交集I

    Problem: Given two arrays, write a function to compute their intersection. 中文:已知两个数组,写一个函数来计算它们的交集 E ...

  6. Laxcus大数据管理系统2.0(11)- 第九章 容错

    第九章 容错 在当前,由于集群庞大的组织体系和复杂性,以及用户普遍要求低成本硬件,使得集群在运行过程中发生的错误概率,远远高于单一且性能稳定的小型机服务器,并且集群在运行过程中几乎是不允许停止的,这就 ...

  7. Tomcat安装后启动一闪而过

    出现这种问题一般是环境变量没配置好.除了JDK环境变量还有Tomcat环境变量:CATALINA_HOME 和CATALINA_BASE 虽然JDK里面会含有JRE,但是最好是在环境变量里面也配置一个 ...

  8. random类的使用

    小栗子a如下: string[] punch = new[] { "石头", "剪刀", "布" }; string myPunch; pu ...

  9. 一个不简单的Procedure body例子

    create or replace package body CountBankData_20150617 is type cursorCommon is ref cursor; --游标类型 str ...

  10. SQL Server 索引和视图

    Ø 索引 1. 什么是索引 索引就是数据表中数据和相应的存储位置的列表,利用索引可以提高在表或视图中的查找数据的速度. 2. 索引分类 数据库中索引主要分为两类:聚集索引和非聚集索引.SQL Serv ...