`
goon
  • 浏览: 183799 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

hadoop学习——IO之ObjectWritable

 
阅读更多

ObjectWritable类主要方法

public void write(DataOutput out) throws IOException {
    writeObject(out, instance, declaredClass, conf);
  }

 public void readFields(DataInput in) throws IOException {
    readObject(in, this, this.conf);
  }

 write是把ObjectWritable对象中的instance写入out,那么instance是从哪里来的呢?

一种方式是通过new时设置的:

  public ObjectWritable(Object instance) {
    set(instance);
  }

 

另一种方式可以通过readFields方法读取的。

然后看看readObject方法是怎么反序列化一个object的:

public static Object readObject(DataInput in, ObjectWritable objectWritable, Configuration conf)
    throws IOException {
    String className = UTF8.readString(in);
    Class<?> declaredClass = PRIMITIVE_NAMES.get(className);
    if (declaredClass == null) {
      try {
        declaredClass = conf.getClassByName(className);
      } catch (ClassNotFoundException e) {
        throw new RuntimeException("readObject can't find class " + className, e);
      }
    }    

    Object instance;
    
    if (declaredClass.isPrimitive()) {            // primitive types

      if (declaredClass == Boolean.TYPE) {             // boolean
        instance = Boolean.valueOf(in.readBoolean());
      } else if (declaredClass == Character.TYPE) {    // char
        instance = Character.valueOf(in.readChar());
      } else if (declaredClass == Byte.TYPE) {         // byte
        instance = Byte.valueOf(in.readByte());
      } else if (declaredClass == Short.TYPE) {        // short
        instance = Short.valueOf(in.readShort());
      } else if (declaredClass == Integer.TYPE) {      // int
        instance = Integer.valueOf(in.readInt());
      } else if (declaredClass == Long.TYPE) {         // long
        instance = Long.valueOf(in.readLong());
      } else if (declaredClass == Float.TYPE) {        // float
        instance = Float.valueOf(in.readFloat());
      } else if (declaredClass == Double.TYPE) {       // double
        instance = Double.valueOf(in.readDouble());
      } else if (declaredClass == Void.TYPE) {         // void
        instance = null;
      } else {
        throw new IllegalArgumentException("Not a primitive: "+declaredClass);
      }

    } else if (declaredClass.isArray()) {              // array
      int length = in.readInt();
      instance = Array.newInstance(declaredClass.getComponentType(), length);
      for (int i = 0; i < length; i++) {
        Array.set(instance, i, readObject(in, conf));
      }
      
    } else if (declaredClass == String.class) {        // String
      instance = UTF8.readString(in);
    } else if (declaredClass.isEnum()) {         // enum
      instance = Enum.valueOf((Class<? extends Enum>) declaredClass, UTF8.readString(in));
    } else {                                      // Writable
      Class instanceClass = null;
      String str = "";
      try {
        str = UTF8.readString(in);
        instanceClass = conf.getClassByName(str);
      } catch (ClassNotFoundException e) {
        throw new RuntimeException("readObject can't find class " + str, e);
      }
      
      Writable writable = WritableFactories.newInstance(instanceClass, conf);
      writable.readFields(in);
      instance = writable;

      if (instanceClass == NullInstance.class) {  // null
        declaredClass = ((NullInstance)instance).declaredClass;
        instance = null;
      }
    }

    if (objectWritable != null) {                 // store values
      objectWritable.declaredClass = declaredClass;
      objectWritable.instance = instance;
    }

    return instance;
      
  }

 可以看出 instance 指向的是java基本类型,或者Array,Enum,或者Writable 。而如果DataInput中传过来的是Writable 类型,则会在readObject再去调用readFields方法(writable.readFields(in)),直到DataInput中传递的是非Writable 类型,就这样递归的反序列化DataInput中的Writable对象。

再看看writeObject方法是如何序列化Writable对象的:

/** Write a {@link Writable}, {@link String}, primitive type, or an array of
   * the preceding. */
  public static void writeObject(DataOutput out, Object instance,
                                 Class declaredClass, 
                                 Configuration conf) throws IOException {

    if (instance == null) {                       // null
      instance = new NullInstance(declaredClass, conf);
      declaredClass = Writable.class;
    }

    UTF8.writeString(out, declaredClass.getName()); // always write declared

    if (declaredClass.isArray()) {                // array
      int length = Array.getLength(instance);
      out.writeInt(length);
      for (int i = 0; i < length; i++) {
        writeObject(out, Array.get(instance, i),
                    declaredClass.getComponentType(), conf);
      }
      
    } else if (declaredClass == String.class) {   // String
      UTF8.writeString(out, (String)instance);
      
    } else if (declaredClass.isPrimitive()) {     // primitive type

      if (declaredClass == Boolean.TYPE) {        // boolean
        out.writeBoolean(((Boolean)instance).booleanValue());
      } else if (declaredClass == Character.TYPE) { // char
        out.writeChar(((Character)instance).charValue());
      } else if (declaredClass == Byte.TYPE) {    // byte
        out.writeByte(((Byte)instance).byteValue());
      } else if (declaredClass == Short.TYPE) {   // short
        out.writeShort(((Short)instance).shortValue());
      } else if (declaredClass == Integer.TYPE) { // int
        out.writeInt(((Integer)instance).intValue());
      } else if (declaredClass == Long.TYPE) {    // long
        out.writeLong(((Long)instance).longValue());
      } else if (declaredClass == Float.TYPE) {   // float
        out.writeFloat(((Float)instance).floatValue());
      } else if (declaredClass == Double.TYPE) {  // double
        out.writeDouble(((Double)instance).doubleValue());
      } else if (declaredClass == Void.TYPE) {    // void
      } else {
        throw new IllegalArgumentException("Not a primitive: "+declaredClass);
      }
    } else if (declaredClass.isEnum()) {         // enum
      UTF8.writeString(out, ((Enum)instance).name());
    } else if (Writable.class.isAssignableFrom(declaredClass)) { // Writable
      UTF8.writeString(out, instance.getClass().getName());
      ((Writable)instance).write(out);

    } else {
      throw new IOException("Can't write: "+instance+" as "+declaredClass);
    }
  }

 在这两个方法中,向数据流中写数据都是用UTF8类,UTF8类相当于一个工具类。

参考:http://caibinbupt.iteye.com/blog/277640

分享到:
评论

相关推荐

    hadoop实战——初级部分学习笔记 2

    ### Hadoop实战——初级部分学习笔记 2 #### 一、引言与背景 随着大数据时代的到来,Hadoop作为处理大规模数据集的核心工具之一,其重要性和应用范围日益扩大。本文将基于私塾在线《Hadoop实战——初级部分》的...

    Hadoop2.7.1——NFS部署

    ### Hadoop 2.7.1 —— NFS 部署详解 #### 一、概述 随着大数据技术的发展,Hadoop作为主流的大数据处理框架之一,其分布式存储系统HDFS得到了广泛的应用。为了提高Hadoop集群的数据访问效率,通常会采用网络文件...

    Hadoop原理——让你快速理解掌握Hadoop

    为何Hadoop是分布式大数据处理的未来?如何掌握Hadoop? Hadoop的历史  始于2002年的apache项目Nutch  2003年Google发表了关于GFS的论文  2004年Nutch的开发者开发了NDFS  2004年Google发表了关于MapReduce的...

    hadoop 权威——指南 第3版

    hadoop 权威指南 第3版,很好的书本,希望大家喜欢。pdf

    org.apache.hadoop.io.nativeio

    必须将此jar包放在org.apache.hadoop.io包下,否则无法正常覆盖使用

    大数据学习指南合集(Hadoop、Spark、Flink等)

    Hadoop——分布式文件管理系统HDFS   2. Hadoop——HDFS的Shell操作   3. Hadoop——HDFS的Java API操作   4. Hadoop——分布式计算框架MapReduce   5. Hadoop——MapReduce案例   6. Hadoop——资源调度器...

    Hadoop-NativeIO.java

    标题 "Hadoop-NativeIO.java" 指涉的核心知识点是 Hadoop 在本地环境下的调试,特别是涉及到 org.apache.hadoop.io.nativeio.NativeIO$Windows.access0 方法的问题。在Hadoop框架中,NativeIO 是一个用于执行低级...

    Hadoop高级编程——构建与实现大数据解决方案.rar

    本压缩包“Hadoop高级编程——构建与实现大数据解决方案”将深入探讨如何利用Hadoop进行高效的数据操作,构建实际的大数据解决方案。 一、Hadoop概述 Hadoop是由Apache基金会开发的开源项目,主要由Hadoop ...

    Hadoop本地调试NativeIO

    在标题“Hadoop本地调试NativeIO”中,我们聚焦的是Hadoop中的一个特定部分——NativeIO。NativeIO是Hadoop的一个特性,它允许使用本地(系统)库进行I/O操作,以提高性能。 NativeIO主要包含两部分:libhadoop.so...

    Hadoop课程实验和报告——Hadoop安装实验报告

    Hadoop课程实验和报告——Hadoop安装实验报告 Hadoop是一个开源的大数据处理框架,由Apache基金会开发和维护。它提供了一种可靠、可扩展、可高效的方法来存储和处理大规模数据。在本实验报告中,我们将介绍Hadoop的...

    Hadoop学习资料

    以上总结的知识点均来自给定文件的内容,涵盖了Hadoop的学习资料、版本历史、生态圈、安装、HDFS、MapReduce、Zookeeper、HBase、Hive、Storm以及数据挖掘和推荐系统等多个方面,为学习和使用Hadoop提供了全面的理论...

    hadoop2.7.6 winutil,NativeIO类

    在这个版本中,本地运行Hadoop时,可能会遇到与`winutils.exe`、`NativeIO`类以及`libwinutils.lib`相关的依赖问题。这些组件在Windows环境下尤其关键,因为Hadoop主要设计在Linux上,但在Windows上运行时需要额外的...

    hadoop2.7.3 hadoop.dll

    org.apache.hadoop.io.nativeio.NativeIO$Windows.createDirectoryWithMode0(Ljava/lang/String;I)V 解决方案:下载本资源解压将hadoop.dll和winutils.exe文件复制到hadoop2.7.3的bin目录下即可解决。

    最新Hadoop生态圈开发学习资料——尚硅谷

    在大数据领域,Hadoop生态圈是不可或缺的重要组成部分,它为海量数据的存储、处理和分析提供了高效可靠的...这份"最新Hadoop生态圈开发学习资料——尚硅谷"将是你学习过程中宝贵的资源,助你在大数据的世界中游刃有余。

    Hadoop学习笔记

    Hadoop学习笔记,自己总结的一些Hadoop学习笔记,比较简单。

    第五章(Hadoop大数据处理实战)Hadoop的IO操作.pdf

    第五章(Hadoop大数据处理实战)Hadoop的IO操作.pdf第五章(Hadoop大数据处理实战)Hadoop的IO操作.pdf第五章(Hadoop大数据处理实战)Hadoop的IO操作.pdf第五章(Hadoop大数据处理实战)Hadoop的IO操作.pdf第五章(Hadoop大...

    windows eclipse 运行wordcount连接linux hadoop2.8 NativeIO YARNRunner 完项目 源码

    在本项目中,我们主要关注的是如何在Windows环境下使用Eclipse IDE运行一个WordCount程序,该程序连接到Linux上的Hadoop 2.8集群,并利用NativeIO和YARNRunner进行分布式处理。以下是对这些关键概念的详细解释: 1....

Global site tag (gtag.js) - Google Analytics