Apache spark 有关spark rdd.saveAsObject文件格式的文档

Apache spark 有关spark rdd.saveAsObject文件格式的文档,apache-spark,Apache Spark,Spark可以使用rdd将rdd保存到文件中。saveAsObjectFile(“文件”)。 我需要在Spark外面读这个文件。根据,使用默认的spark序列化程序,该文件只是一个用标准Java序列化的对象序列。但是,我猜文件在对象之间有一个头和一个分隔符。我需要读取此文件,并使用来反序列化每个Java/Scala对象(因为我没有类定义) 在哪里可以找到关于rdd.saveAsObjectFile(“文件”)生成的文件格式的文档(使用标准序列化程序,而不是Kryo序列化程序) 更新 基于Vla

Spark可以使用
rdd将rdd保存到文件中。saveAsObjectFile(“文件”)
。 我需要在Spark外面读这个文件。根据,使用默认的spark序列化程序,该文件只是一个用标准Java序列化的对象序列。但是,我猜文件在对象之间有一个头和一个分隔符。我需要读取此文件,并使用来反序列化每个Java/Scala对象(因为我没有类定义)

在哪里可以找到关于rdd.saveAsObjectFile(“文件”)生成的文件格式的文档(使用标准序列化程序,而不是Kryo序列化程序)


更新 基于VladoDemcak答案的工作示例:

import org.apache.hadoop.io._
import org.apache.hadoop.conf._
import org.apache.hadoop.fs._
import org.apache.hadoop.io._

def deserialize(data: Array[Byte]) =
  new ObjectInputStream(new ByteArrayInputStream(data)).readObject()

val path = new Path("/tmp/part-00000")
val config = new Configuration()
val reader = new SequenceFile.Reader(FileSystem.get(new Configuration()), path, config)
val key = NullWritable.get
val value = new BytesWritable

while (reader.next(key, value)) {
  println("key: {} and value: {}.", key, value.getBytes)
  println(deserialize(value.getBytes()))
}
reader.close()

这是一个非常有趣的问题,所以我将尝试解释一下我对这些员工的了解。你可以查看我看到的关于一些细节的文档

据我所知,
saveAsObjectFile
products。根据sequenceFile的文档,它的标题为
版本
类名
元数据

有3种不同的SequenceFile格式:

未压缩的键/值记录。记录压缩键/值记录- 此处仅压缩“值”。阻止压缩键/值记录 -键和值都分别收集在“块”中并进行压缩。“块”的大小是可配置的

以上所有格式都共享一个公共标头(由 SequenceFile.Reader返回相应的键/值对)

对于读取sequencefile,我们可以使用hadoop实现

Path path = new Path("/hdfs/file/path/seqfile");
SequenceFile.Reader reader = new SequenceFile.Reader(FileSystem.get(new Configuration()), path, config);
WritableComparable key = (WritableComparable) reader.getKeyClass().newInstance();
Writable value = (Writable) reader.getValueClass().newInstance();

while (reader.next(key, value)){
     logger.info("key: {} and value: {}.", key, value.getBytes());
     // (MyObject) deserialize(value.getBytes());
}

reader.close();
我没有对此进行测试,但基于您在问题中注意到的链接:

默认情况下,Spark使用Java的ObjectOutputStream序列化对象 框架

所以在循环中,您可以获取值的字节,并使用
ObjectInputStream

public static Object deserialize(byte[] data){
    return new ObjectInputStream(new ByteArrayInputStream(data)).readObject();
}

在您的情况下,您需要在反序列化方法中使用您的库(jdeserialize)——我猜
run(InputStream是,boolean shouldConnect)
等等。

我在调用
reader.getKeyClass().newInstance()
时遇到运行时错误,请参阅我的问题更新。有什么想法吗?它有效;我已经用代码更新了问题。谢谢
public static Object deserialize(byte[] data){
    return new ObjectInputStream(new ByteArrayInputStream(data)).readObject();
}