Как читать GZ-файлы в Spark с помощью wholeTextFiles
у меня есть папка, которая содержит множество мелких .GZ файлы (сжатые текстовые файлы csv). Мне нужно прочитать их в моей работе Spark, но дело в том, что мне нужно сделать некоторую обработку на основе информации, которая находится в имени файла. Поэтому я не использовал:
JavaRDD<<String>String> input = sc.textFile(...)
поскольку, насколько я понимаю, у меня нет доступа к имени файла таким образом. Вместо этого я использовал:
JavaPairRDD<<String>String,String> files_and_content = sc.wholeTextFiles(...);
потому что таким образом я могу получить имя файла и контента. Однако, похоже, что таким образом, читатель ввода не удается прочитать текст из файла GZ, а читает двоичный мусор.
Итак, я хотел бы знать, могу ли я установить его каким-то образом прочитать текст или альтернативно получить доступ к имени файла с помощью sc.textFile(...)
2 ответов
вы не можете читать gzipped файлы с wholeTextFiles, потому что он использует CombineFileInputFormat, который не может читать gzipped файлы, потому что они не расщепляются (источник, доказывающий это):
override def createRecordReader(
split: InputSplit,
context: TaskAttemptContext): RecordReader[String, String] = {
new CombineFileRecordReader[String, String](
split.asInstanceOf[CombineFileSplit],
context,
classOf[WholeTextFileRecordReader])
}
вы можете использовать newAPIHadoopFile
С wholefileinputformat
(не встроенный в hadoop, но по всему интернету), чтобы заставить это работать правильно.
обновление 1: я не думаю, что WholeFileInputFormat будет работать, так как он просто получает байты файл, то есть вам, возможно, придется написать свой собственный класс, возможно, расширяя WholeFileInputFormat, чтобы убедиться, что он распаковывает байты.
другой вариант-распаковать байты самостоятельно, используя GZipInputStream
обновление 2: если у вас есть доступ к имени папки в ФП ниже вы можете получить все файлы.
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());
я столкнулся с той же проблемой при использовании spark для подключения к S3.
мой файл был gzip csv без расширения .
JavaPairRDD<String, String> fileNameContentsRDD = javaSparkContext.wholeTextFiles(logFile);
этот подход вернул currupted значения
Я решил это, используя следующий код:
JavaPairRDD<String, String> fileNameContentsRDD = javaSparkContext.wholeTextFiles(logFile+".gz");
путем добавления .GZ к URL S3, spark автоматически выбрал файл и прочитал его как файл gz .(Кажется, неправильный подход, но решил мою проблему .