【问题标题】:Spark Reading .7z filesSpark 读取 .7z 文件
【发布时间】:2021-02-05 21:22:24
【问题描述】:

我正在尝试使用 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

压缩文件代码

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();
        }
    }

经过这么多年的火花进化,应该有简单的方法来做到这一点。

【问题讨论】:

  • 如果文件以example.7z的二进制形式存储在hdfs中,你能解释一下吗?
  • @silentsudo,是的,文件存储在 hdfs 中
  • @silentsudo 文件存储在 hdfs 中。

标签: java scala apache-spark hdfs 7zip


【解决方案1】:

您可以尝试SeekableByteChannel 方法,而不是使用基于java.io.File 的方法,如alternative constructor 所示。

您可以使用SeekableInMemoryByteChannel 来读取字节数组。因此,只要您可以从 S3 或其他任何地方获取 7zip 文件并将它们作为字节数组传递,就可以了。

综上所述,Spark 确实不适合处理 zip 和 7zip 文件之类的文件。我可以从个人经验告诉你,一旦文件太大而 Spark 的执行程序无法处理,我已经看到它会严重失败。

像 Apache NiFi 这样的东西在扩展档案和处理它们方面会更好。 FWIW,我目前正在处理一个大型数据转储,我经常处理其中包含数百万个文件的 50GB 压缩包,而 NiFi 非常优雅地处理它们。

【讨论】:

  • 我们如何将 PortableDataStream 传递到 SeekableInMemoryByteChannel。
  • 你能帮我将 PortableDataStream 传递到 SeekableInMemoryByteChannel
  • 我对 spark 了解不多,因此您将不得不自己进行试验。也就是说,我强烈建议您不要将 Spark 与压缩档案一起使用。这是一个非常糟糕的工具不匹配,几乎永远不会成功。
猜你喜欢
  • 2019-04-18
  • 1970-01-01
  • 2019-05-11
  • 1970-01-01
  • 1970-01-01
  • 2019-11-12
  • 2019-07-10
  • 2017-04-08
  • 1970-01-01
相关资源
最近更新 更多