Apache Spark 读取 .7z 文件

5

我正在尝试使用Scala或Java读取Spark的.7z文件。我没有找到任何适当的方法或功能。

对于zip文件,我可以读取它,因为ZipInputStream类需要输入流,但是对于.7z文件,SevenZFile类不接受任何输入流。 https://commons.apache.org/proper/commons-compress/javadocs/api-1.16/org/apache/commons/compress/archivers/sevenz/SevenZFile.html

zip文件代码

spark.sparkContext.binaryFiles("fileName").flatMap{case (name: String, content: PortableDataStream) =>
        val zis = new ZipInputStream(content.open)
        Stream.continually(zis.getNextEntry)
              .takeWhile(_ != null)
              .flatMap { _ =>
                  val br = new BufferedReader(new InputStreamReader(zis))
                  Stream.continually(br.readLine()).takeWhile(_ != null)
              }}

我正在尝试类似的代码来处理7z文件,类似于:

spark.sparkContext.binaryFiles(""filename"").flatMap{case (name: String, content: PortableDataStream) =>
        val zis = new SevenZFile(content.open)
        Stream.continually(zis.getNextEntry)
              .takeWhile(_ != null)
              .flatMap { _ =>
                  val br = new BufferedReader(new InputStreamReader(zis))
                  Stream.continually(br.readLine()).takeWhile(_ != null)
              }}

但是SevenZFile不接受这些格式。正在寻找解决方案。

如果文件在本地文件系统中,则以下解决方案有效,但我的文件在HDFS中。

本地文件系统代码

 public static void decompress(String in, File destination) throws IOException {
        SevenZFile sevenZFile = new SevenZFile(new File(in));
        SevenZArchiveEntry entry;
        while ((entry = sevenZFile.getNextEntry()) != null){
            if (entry.isDirectory()){
                continue;
            }
            File curfile = new File(destination, entry.getName());
            File parent = curfile.getParentFile();
            if (!parent.exists()) {
                parent.mkdirs();
            }
            FileOutputStream out = new FileOutputStream(curfile);
            byte[] content = new byte[(int) entry.getSize()];
            sevenZFile.read(content, 0, content.length);
            out.write(content);
            out.close();
        }
    }

经过这么多年Spark的发展,现在应该有一种简单的方法来做到它。


请问文件是否以二进制形式存储在HDFS中,例如example.7z - silentsudo
@silentsudo,是的,这些文件存储在HDFS中。 - loneStar
@silentsudo 文件存储在HDFS中。 - loneStar
1个回答

4

与其使用基于java.io.File的方法,不如尝试使用SeekableByteChannel方法,可以通过此替代构造函数进行展示。

您可以使用SeekableInMemoryByteChannel来读取字节数组。只要您可以从S3或其他地方获取7zip文件并将它们作为字节数组传递,那么就应该没问题了。

话虽如此,Spark真的不适合处理像zip和7zip文件这样的东西。从我的个人经验来看,一旦文件太大,超过了Spark执行器的处理能力,它就会失败得很惨。

像Apache NiFi这样的工具将更适合扩展存档文件并处理它们。值得一提的是,我目前正在处理一个大型数据转储,其中我经常处理有数百万个文件的50GB tarball,并且NiFi处理它们非常优雅。


我们如何将PortableDataStream传递到SeekableInMemoryByteChannel中? - loneStar
你能帮我将PortableDataStream传递到SeekableInMemoryByteChannel中吗? - loneStar
我对Spark并不了解,所以你需要自己进行实验。话虽如此,我强烈建议你不要在压缩文件上使用Spark。这是一种非常糟糕的工具匹配方式,基本上不起作用。 - Mike Thomsen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接