Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/apache-spark/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala:如何从RDD获取PortableDataStream实例的内容_Scala_Apache Spark_Rdd - Fatal编程技术网

Scala:如何从RDD获取PortableDataStream实例的内容

Scala:如何从RDD获取PortableDataStream实例的内容,scala,apache-spark,rdd,Scala,Apache Spark,Rdd,当我想从二进制文件中提取数据时,我使用 val dataRDD=sc.binaryRecord(“Path”)我得到的结果是org.apache.spark.rdd.rdd[(String,org.apache.spark.input.PortableDataStream)] 我想以PortableDataStream 为此,我尝试了:val data=dataRDD.map(x=>x.\u 2.open()).collect() 但我得到了以下错误: java.io.NotSerializab

当我想从二进制文件中提取数据时,我使用
val dataRDD=sc.binaryRecord(“Path”)
我得到的结果是
org.apache.spark.rdd.rdd[(String,org.apache.spark.input.PortableDataStream)]

我想以
PortableDataStream

为此,我尝试了:
val data=dataRDD.map(x=>x.\u 2.open()).collect()
但我得到了以下错误:
java.io.NotSerializableException:org.apache.hadoop.hdfs.client.HdfsDataInputStream

如果你有一个想法,我可以如何解决我的问题,请帮助


非常感谢。

实际上,
PortableDataStream
是可序列化的。这就是它的意义所在。然而,
open()
返回一个简单的
DataInputStream
HdfsDataInputStream
,因为您的文件在HDFS上),它是不可序列化的,因此会出现错误

事实上,当您打开PortableDataStream时,您只需要立即读取数据。在scala中,您可以使用
scala.io.Source.fromInputStream

val数据:RDD[Array[String]]=sc
.binaryFiles(“路径/../”)
.map{case(文件名,pds)=>{
scala.io.Source.fromInputStream(pds.open())
.getLines().toArray
}}
此代码假定数据是文本的。如果不是,您可以调整它以读取任何类型的二进制数据。下面是一个创建字节序列的示例,您可以按照自己的方式处理该序列

val rdd : RDD[Seq[Byte]] = sc.binaryFiles("...")
    .map{ case (file, pds) => {
        val dis = pds.open()
        val bytes = Array.ofDim[Byte](1024)
        val all = scala.collection.mutable.ArrayBuffer[Byte]()
        while( dis.read(bytes) != -1) {
            all ++= bytes
        }
        all.toSeq
    }}
有关更多可能性,请参阅。例如,它拥有
readLong
readDouble
(等等)方法 val bytes=bf.map{case(file,pds)=>{ val dis=pds.open() val len=dis.available(); val buf=数组。ofDim[字节](len) pds.open().readFully(buf) 缓冲器 }} bytes:org.apache.spark.rdd.rdd[Array[Byte]]=MapPartitionsRDD[21]位于map at:26 scala>bytes.take(1)(0).size res15:Int=5879609//这恰好是我的第一个二进制文件的大小
感谢您的回复。我已经尝试了您的解决方案,缺少一个“}”,并且我应该将
.toSeq()
编辑到
.toSeq
否则它会给我
错误:没有足够的参数用于trait SeqLike中的方法apply:(idx:Int)字符串。尽管解决方案给出了
错误调度器.TaskSetManager:阶段1.0中的任务0失败1次;正在中止作业
对不起,我没有测试所有代码。我修正了我的答案。它实际上不适用于
toSeq
,可能是因为它只是基于inputStream封装了迭代器
toArray
相反,实际提取数据以将其放入数组中。我在答案中修改了它。感谢您的反馈;)感谢@Oli的回复。问题仍然存在
java.nio.charset.MalformedInputException:Input length=1
OK,这是不同的。你在读什么样的数据?这只是字符串的一个示例。如果您读取二进制数据,它将无法工作,您必须调整代码。。。
val bf    = sc.binaryFiles("...")
val bytes = bf.map{ case(file, pds) => {
    val dis = pds.open()
    val len = dis.available();
    val buf = Array.ofDim[Byte](len)
    pds.open().readFully(buf)
    buf
}}
bytes: org.apache.spark.rdd.RDD[Array[Byte]] = MapPartitionsRDD[21] at map at <console>:26

scala> bytes.take(1)(0).size
res15: Int = 5879609  // this happened to be the size of my first binary file