我正在学习 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 类型,它们指的是实现这些接口(interface)的类的对象。所以我的第二个问题是,这些引用类型本身是字节流吗?我在这里很困惑,这里如何生成字节流以像在 hadoop 中一样在网络上进行读写操作?
最后一个问题,相同的代码如何与正在进行序列化的机器上的数据通信,以及在数据到达那里后如何与网络上正在进行反序列化的另一台机器通信?这种联系如何在网络上使用相同代码进行序列化/反序列化时发生?
最佳答案
为什么总是需要将数据转换成字节进行序列化/反序列化?
序列化的目的是将数据发送到您的软件之外的某个地方(您的硬盘驱动器或某个地方的其他软件)。这些进程将需要通用的低级数据表示,例如要传输的字节。
_
这些引用类型本身是字节流吗?它们从那里读取或写入字节?我在这里很困惑,这里如何生成字节流以像在 hadoop 中一样在网络上进行读写操作?
它们不是字节流。它们和其他任何类一样都是 Java 类,但它们在内部保存字节流。您可以检查这些接口(interface)的一个实现的代码,看看它们如何更好地工作,例如 DataInputStream,您将能够看到它们保存在字节数组中。以字节为单位的实际读取和写入是非常低级的东西,实际上我不确定它到底是如何完成的,但是如果你继续深入这些实现是有可能弄清楚的。
_
同一代码如何与正在进行序列化的机器上的数据通信,以及在数据到达后如何与网络上正在进行反序列化的另一台机器通信?
为了能够反序列化对象,目标也需要具有用于序列化的相同 Java 对象。为确保两个类在源和目标上都相等,这样在反序列化时不会得到意外结果,建议您生成一个 serialVersionUID,如下所示:
private static final long serialVersionUID = 3770035753852147836L;
关于java - Java 基本类型的包装器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46844149/