我有一个包含许多小.gz文件的文件夹(压缩的csv文本文件)。我需要在我的Spark工作中阅读它们,但问题是我需要根据文件名中的信息进行一些处理。因此,我没有使用:
JavaRDD<<String>String> input = sc.textFile(...)
因为据我所知,我无法以这种方式访问文件名。相反,我用过:
JavaPairRDD<<String>String,String> files_and_content = sc.wholeTextFiles(...);
因为这样我获得了一对文件名和内容。 但是,似乎这样,输入阅读器无法从gz文件中读取文本,而是读取二进制Gibberish。
所以,我想知道我是否可以设置它以某种方式阅读文本,或者使用sc.textFile(...)
答案 0 :(得分:2)
您无法使用wholeTextFiles读取gzip压缩文件,因为它使用了无法读取gzip压缩文件的CombineFileInputFormat,因为they are not splittable(来源证明):
override def createRecordReader(
split: InputSplit,
context: TaskAttemptContext): RecordReader[String, String] = {
new CombineFileRecordReader[String, String](
split.asInstanceOf[CombineFileSplit],
context,
classOf[WholeTextFileRecordReader])
}
您可以将newAPIHadoopFile
与wholefileinputformat
一起使用(不是内置于hadoop中,但在整个互联网上)以使其正常工作。
UPDATE 1:我不认为WholeFileInputFormat会工作,因为它只是获取文件的字节,这意味着您可能必须编写自己的类,可能会扩展WholeFileInputFormat以确保它解压缩字节
另一种选择是使用GZipInputStream
自行解压缩字节更新2:如果你有权访问目录名,就像下面OP的评论一样,你可以得到这样的所有文件。
Path path = new Path("");
FileSystem fileSystem = path.getFileSystem(new Configuration()); //just uses the default one
FileStatus [] fileStatuses = fileSystem.listStatus(path);
ArrayList<Path> paths = new ArrayList<>();
for (FileStatus fileStatus : fileStatuses) paths.add(fileStatus.getPath());
答案 1 :(得分:0)
使用spark连接S3时遇到了同样的问题。
我的文件是一个没有扩展名的gzip csv。
JavaPairRDD<String, String> fileNameContentsRDD = javaSparkContext.wholeTextFiles(logFile);
此方法返回了已损坏的值
我使用下面的代码解决了它:
JavaPairRDD<String, String> fileNameContentsRDD = javaSparkContext.wholeTextFiles(logFile+".gz");
通过将.gz添加到S3 URL,spark会自动选择文件并像gz文件一样读取它。(看似错误的方法但解决了我的问题。