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. Ubuntu Qt arm-linux-androideabi-gcc: Command not found

    :-1: error: /opt/Qt/android-ndk-r9c/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86/bin/arm- ...

  2. python写入中文到文件乱码的问题

    file = open(filename,'a',encoding='utf8')#指定写入编码为utf8,否则写入中文会乱码

  3. C#程序用Inno Setup打包,以管理员身份运行的处理方法

    一.C#项目端的处理 目标:快捷方式有带盾的标识 在源码的Properties目录中找到 app.manifest,将其中level="asInvoker" 改成 level=&q ...

  4. freeglut第一步

    #include <GL/freeglut.h> static void RenderSceneCB() { glClear(GL_COLOR_BUFFER_BIT); glutSwapB ...

  5. Maven本地资源库

    在本地安装的mvn文件夹中找到conf/setting.xml,然后找到localRepository结点,这个路径值就是Maven的实际路径 打开该文件夹就能够看到

  6. robotframework+ride+Selenium2Library+AutoItLibrary配置

    最近要安装RFS,虽然网上很多安装说明,但是自己装的时候还是遇到了很多问题. 1. AutoLibrary导入失败:猜测原因是AutoLibrary需要先安装pywin32,而我一开始安装的是pyth ...

  7. xml 和 json 的区别

    JSON(Javascript Object Notation) 是一种轻量级的数据交换格式.易于人阅读和编写.同时也易于机器解析和生成.它基于Javascript Programming Langu ...

  8. oracle通过DBlink连接mysql(MariaDB)

    1.安装先装 mysql-connector-odbc(或 mariadb-connector-odbc )和unixODBChttps://downloads.mariadb.org/mariadb ...

  9. 学习练习 java数据库查询小题

    10. 查询Score表中的最高分的学生学号和课程号.(子查询或者排序) 11. 查询每门课的平均成绩. 12.查询Score表中至少有5名学生选修的并以3开头的课程的平均分数. 13.查询分数大于7 ...

  10. Ossim主要功能实战

    Ossim主要功能实战 OSSIM通过将开源产品进行集成,从而提供一种能够实现安全监控功能的基础平台将Nagiso,Ntop,Snort,Nmap等开源工具集成在一起提供综合的安全保护功能,而不必在各 ...