围绕Java原始类型的包装器

时间:2017-10-20 07:19:32

标签: java hadoop serialization deserialization

我正在学习hadoop并且只知道Java的基本概念。在研究hadoop时,我发现hadoop使用了自己的类型,如Longwritable,Text etch,它们是Java原始类型的扩展或包装版本。

我在java社区发布了这个问题,因为我认为这些是唯一可以解除疑虑的人。

我打算全面了解这个概念,不仅因为它与hadoop相关,而且它对我来说非常有趣,并且可以在任何地方使用,而不仅仅用于hadoop。

在阅读时我发现hadoop这样做是为了让他们能够非常快速地在网络上移动数据。它可以通过序列化和反序列化来完成。对于这个概念,可以使用Dataoutput,它从任何Java基元类型读取数据并转换为一系列字节,然后使用Datainput再次读取这些字节并转换回其原始状态。

我的第一个问题是,为什么总是需要将数据转换为字节以进行序列化/反序列化?我听说字节的重量比实际数据低,所以这是唯一的原因吗?还有其他原因吗?

第二个问题,当我们进行序列化和反序列化时,可以说使用以下代码

public class LongWritable implements Writable {
       // Some data     
       private int counter;
       private long timestamp;

       public void write(DataOutput out) throws IOException {
         out.writeInt(counter);
         out.writeLong(timestamp);
       }

       public void readFields(DataInput in) throws IOException {
         counter = in.readInt();
         timestamp = in.readLong();
       }

       public static LongWritable read(DataInput in) throws IOException {
         LongWritable w = new LongWritable();
         w.readFields(in);
         return w;
       }
     }

所以这里我们使用的是DataInput和DataOutput类型,它指的是实现这些接口的类的对象。所以我的第二个问题是,这些引用类型本身是字节流,它们从哪里读取或写入字节?我在这里感到困惑,这里如何生成字节流来在网络上读取和写入操作,就像在hadoop中一样?

最后一个问题,相同的代码如何与正在进行序列化的机器上的数据以及网络上的另一台机器进行通信,一旦数据到达那里就进行了反序列化?如何通过网络使用相同的代码序列化/反序列化这种联系?

1 个答案:

答案 0 :(得分:0)

为什么总是需要将数据转换为字节以进行序列化/反序列化?

序列化的目的是将数据发送到软件之外的某个地方(您的硬盘或某处的其他软件)。这些过程需要通用的低级数据表示,例如要传输的字节。

_

这些引用类型本身是字节流,它们从哪里读取或写入字节?我在这里很困惑,这里如何生成字节流来在网络上读取和写入操作,就像在hadoop一样?

它们不是字节流。它们是与其他类似的Java类,但它们在内部保存字节流。您可以检查这些接口的一个实现的代码,看看它们如何更好地工作,比如DataInputStream,您将能够看到它们保存在字节数组中。实际的读取和写入字节是非常低级的东西,我实际上不确定它是如何完成的,但是有可能弄清楚你是否继续深入研究这些实现。

_

相同的代码如何与正在进行序列化的机器上的数据以及网络上的另一台机器进行通信,一旦数据到达那里就进行了反序列化?

为了能够反序列化对象,目标需要具有与序列化相同的Java对象。为确保源和目标上的两个类都相同,因此在反序列化时不会出现意外结果,建议您生成如下的serialVersionUID:

private static final long serialVersionUID = 3770035753852147836L;