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作为处理大规模数据集的核心工具之一,其重要性和应用范围日益扩大。本文将基于私塾在线《Hadoop实战——初级部分》的...
### Hadoop 2.7.1 —— NFS 部署详解 #### 一、概述 随着大数据技术的发展,Hadoop作为主流的大数据处理框架之一,其分布式存储系统HDFS得到了广泛的应用。为了提高Hadoop集群的数据访问效率,通常会采用网络文件...
为何Hadoop是分布式大数据处理的未来?如何掌握Hadoop? Hadoop的历史 始于2002年的apache项目Nutch 2003年Google发表了关于GFS的论文 2004年Nutch的开发者开发了NDFS 2004年Google发表了关于MapReduce的...
hadoop 权威指南 第3版,很好的书本,希望大家喜欢。pdf
必须将此jar包放在org.apache.hadoop.io包下,否则无法正常覆盖使用
Hadoop——分布式文件管理系统HDFS 2. Hadoop——HDFS的Shell操作 3. Hadoop——HDFS的Java API操作 4. Hadoop——分布式计算框架MapReduce 5. Hadoop——MapReduce案例 6. Hadoop——资源调度器...
标题 "Hadoop-NativeIO.java" 指涉的核心知识点是 Hadoop 在本地环境下的调试,特别是涉及到 org.apache.hadoop.io.nativeio.NativeIO$Windows.access0 方法的问题。在Hadoop框架中,NativeIO 是一个用于执行低级...
本压缩包“Hadoop高级编程——构建与实现大数据解决方案”将深入探讨如何利用Hadoop进行高效的数据操作,构建实际的大数据解决方案。 一、Hadoop概述 Hadoop是由Apache基金会开发的开源项目,主要由Hadoop ...
在标题“Hadoop本地调试NativeIO”中,我们聚焦的是Hadoop中的一个特定部分——NativeIO。NativeIO是Hadoop的一个特性,它允许使用本地(系统)库进行I/O操作,以提高性能。 NativeIO主要包含两部分:libhadoop.so...
Hadoop课程实验和报告——Hadoop安装实验报告 Hadoop是一个开源的大数据处理框架,由Apache基金会开发和维护。它提供了一种可靠、可扩展、可高效的方法来存储和处理大规模数据。在本实验报告中,我们将介绍Hadoop的...
以上总结的知识点均来自给定文件的内容,涵盖了Hadoop的学习资料、版本历史、生态圈、安装、HDFS、MapReduce、Zookeeper、HBase、Hive、Storm以及数据挖掘和推荐系统等多个方面,为学习和使用Hadoop提供了全面的理论...
在这个版本中,本地运行Hadoop时,可能会遇到与`winutils.exe`、`NativeIO`类以及`libwinutils.lib`相关的依赖问题。这些组件在Windows环境下尤其关键,因为Hadoop主要设计在Linux上,但在Windows上运行时需要额外的...
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的IO操作.pdf第五章(Hadoop大数据处理实战)Hadoop的IO操作.pdf第五章(Hadoop大数据处理实战)Hadoop的IO操作.pdf第五章(Hadoop大数据处理实战)Hadoop的IO操作.pdf第五章(Hadoop大...
在本项目中,我们主要关注的是如何在Windows环境下使用Eclipse IDE运行一个WordCount程序,该程序连接到Linux上的Hadoop 2.8集群,并利用NativeIO和YARNRunner进行分布式处理。以下是对这些关键概念的详细解释: 1....