Apache spark Spark:使用与新行不同的分隔符读取文件
我正在使用ApacheSpark1.0.1。我有许多文件是用UTF8Apache spark Spark:使用与新行不同的分隔符读取文件,apache-spark,Apache Spark,我正在使用ApacheSpark1.0.1。我有许多文件是用UTF8\u0001分隔的,而不是通常的新行\n分隔的。如何在Spark中读取此类文件?也就是说,sc.textfile(“hdfs:///myproject/*“是\n,我想将其更改为\u0001您可以使用textinputformat.record.delimiter设置textinputformat的分隔符,例如 import org.apache.hadoop.conf.Configuration import org.apac
\u0001
分隔的,而不是通常的新行\n
分隔的。如何在Spark中读取此类文件?也就是说,sc.textfile(“hdfs:///myproject/*“
是\n
,我想将其更改为\u0001
您可以使用textinputformat.record.delimiter
设置textinputformat
的分隔符,例如
import org.apache.hadoop.conf.Configuration
import org.apache.hadoop.mapreduce.Job
import org.apache.hadoop.io.{LongWritable, Text}
import org.apache.hadoop.mapreduce.lib.input.TextInputFormat
val conf = new Configuration(sc.hadoopConfiguration)
conf.set("textinputformat.record.delimiter", "X")
val input = sc.newAPIHadoopFile("file_path", classOf[TextInputFormat], classOf[LongWritable], classOf[Text], conf)
val lines = input.map { case (_, text) => text.toString}
println(lines.collect)
例如,我的输入是一个包含一行的文件aXbXcXd
。将输出上述代码
Array(a, b, c, d)
在Spark shell中,我根据以下公式提取数据:
$spark shell
...
scala>import org.apache.hadoop.io.LongWritable
导入org.apache.hadoop.io.LongWritable
scala>import org.apache.hadoop.io.Text
导入org.apache.hadoop.io.Text
scala>import org.apache.hadoop.conf.Configuration
导入org.apache.hadoop.conf.Configuration
scala>import org.apache.hadoop.mapreduce.lib.input.TextInputFormat
导入org.apache.hadoop.mapreduce.lib.input.TextInputFormat
scala>val conf=新配置
conf:org.apache.hadoop.conf.Configuration=Configuration:core-default.xml、core-site.xml、mapred-default.xml、mapred-site.xml、warn-default.xml、warn-site.xml
scala>conf.set(“textinputformat.record.delimiter”,“\u0001”)
scala>val data=sc.newAPIHadoopFile(“mydata.txt”,classOf[TextInputFormat],classOf[LongWritable],classOf[Text],conf).map(u.\u 2.toString)
数据:org.apache.spark.rdd.rdd[(org.apache.hadoop.io.LongWritable,org.apache.hadoop.io.Text)]=NewHadoopRDD[0]位于newAPIHadoopFile:19
sc.newapiHadoop文件(“mydata.txt”,…)
是一个RDD[(LongWritable,Text)]
,其中元素的第一部分是起始字符索引,第二部分是python中由“\u0001”
分隔的实际文本。这可以通过以下方法实现:
rdd = sc.newAPIHadoopFile(YOUR_FILE, "org.apache.hadoop.mapreduce.lib.input.TextInputFormat",
"org.apache.hadoop.io.LongWritable", "org.apache.hadoop.io.Text",
conf={"textinputformat.record.delimiter": YOUR_DELIMITER}).map(lambda l:l[1])
以下是适用于Scala用户的“s”和“s答案”的现成版本,可通过以下方式使用:
sc.textFile(“some/path.txt”,“u0001”)
下面的代码段使用隐式类创建了一个附加的textFile
方法,该方法隐式附加到SparkContext
(以复制SparkContext
的默认textFile
方法):
package.com
导入org.apache.spark.SparkContext
导入org.apache.spark.rdd.rdd
导入org.apache.hadoop.conf.Configuration
导入org.apache.hadoop.io.{LongWritable,Text}
导入org.apache.hadoop.mapreduce.lib.input.TextInputFormat
物体火花{
隐式类contextensions(val sc:SparkContext)扩展了AnyVal{
def文本文件(
路径:字符串,
分隔符:字符串,
maxRecordLength:String=“1000000”
):RDD[String]={
val conf=新配置(sc.hadoopConfiguration)
//此配置设置记录分隔符:
conf.set(“textinputformat.record.delimiter”,delimiter)
//这一条限制了一条记录的大小:
conf.set(“mapreduce.input.linerecordreader.line.maxlength”,maxRecordLength)
sc.newapiHadoop文件(
路径
classOf[TextInputFormat],classOf[LongWritable],classOf[Text],
形态
)
.map{case({,text)=>text.toString}
}
}
}
可以这样使用:
import com.whatever.Spark.contextensions
sc.textFile(“some/path.txt”,“\u0001”)
请注意额外的设置mapreduce.input.linerecordreader.line.maxlength
,它限制了记录的最大大小。当从损坏的文件中读取一条记录可能太长而无法放入内存时(使用记录分隔符时发生这种情况的可能性更大),这一点非常方便
使用此设置,当读取损坏的文件时,将抛出异常(java.io.IOException
-因此可捕获),而不是从内存中取出一个乱七八糟的文件,从而停止SparkContext。如果您使用的是spark上下文,下面的代码对我有帮助
sc.hadoopConfiguration.set(“textinputformat.record.delimiter”、“delimeter”)
当我在spark shell中运行上述代码时,我收到以下错误:scala>val job=new job(sc.hadoopConfiguration)警告:有1个弃用警告;使用-depredition重新运行java.lang.IllegalStateException:作业处于状态定义而不是运行在org.apache.hadoop.mapreduce.Job.EnsureRate(Job.java:283)如何修复此“java.lang.IllegalStateException:作业处于状态定义而不是运行”问题?能否将完整堆栈轨迹粘贴到某个位置并提供链接?
rdd = sc.newAPIHadoopFile(YOUR_FILE, "org.apache.hadoop.mapreduce.lib.input.TextInputFormat",
"org.apache.hadoop.io.LongWritable", "org.apache.hadoop.io.Text",
conf={"textinputformat.record.delimiter": YOUR_DELIMITER}).map(lambda l:l[1])