You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Scala中读取多个7z压缩包内CSV文件内容的方法求助

我来帮你搞定这个问题!在Scala里读取7z压缩包内的CSV文件,核心是用支持7z格式的压缩库配合CSV解析工具,下面是一步步的实现方案:

在Scala中读取7z压缩包内的CSV文件内容

第一步:添加必要的依赖

首先得在你的sbt项目里引入支持7z解压的Apache Commons Compress,以及用于解析CSV的通用库。在build.sbt里加上以下依赖:

libraryDependencies ++= Seq(
  "org.apache.commons" % "commons-compress" % "1.26.0",
  "org.apache.commons" % "commons-csv" % "1.10.0",
  "commons-io" % "commons-io" % "2.16.1" // 辅助简化IO操作
)

第二步:编写读取7z内CSV的工具方法

下面是封装好的工具类,能处理单个7z文件,遍历其中的CSV条目并解析内容:

import org.apache.commons.compress.archivers.sevenz.{SevenZArchiveEntry, SevenZFile}
import org.apache.commons.csv.{CSVFormat, CSVParser}
import java.io.{BufferedReader, File, InputStreamReader}
import scala.jdk.CollectionConverters._

object SevenZCSVReader {
  // 处理单个7z文件,返回所有CSV文件的内容(每行以字段列表形式存储)
  def readCSVsFrom7z(sevenZFilePath: String): List[List[List[String]]] = {
    val sevenZFile = new SevenZFile(new File(sevenZFilePath))
    var currentEntry: Option[SevenZArchiveEntry] = Option(sevenZFile.getNextEntry)
    val csvContents = scala.collection.mutable.ListBuffer[List[List[String]]]()

    try {
      while (currentEntry.isDefined) {
        val entry = currentEntry.get
        // 只处理CSV文件,跳过目录和非CSV类型的文件
        if (!entry.isDirectory && entry.getName.toLowerCase.endsWith(".csv")) {
          println(s"正在读取压缩包内的文件: ${entry.getName}")
          // 读取压缩包内的文件流
          val reader = new BufferedReader(new InputStreamReader(sevenZFile))
          // 用带表头的格式解析CSV(如果你的CSV无表头,去掉withHeader()即可)
          val csvParser = new CSVParser(reader, CSVFormat.DEFAULT.withHeader())
          // 将Java集合转换为Scala集合,提取每行的字段
          val rows = csvParser.getRecords.asScala.map(record => record.asScala.toList).toList
          csvContents.append(rows)
          // 及时关闭资源
          csvParser.close()
          reader.close()
        }
        currentEntry = Option(sevenZFile.getNextEntry)
      }
      csvContents.toList
    } finally {
      // 确保7z文件流最终关闭
      sevenZFile.close()
    }
  }

  // 批量处理多个7z文件,合并所有CSV内容
  def readCSVsFromMultiple7Zs(sevenZFilePaths: List[String]): List[List[List[String]]] = {
    sevenZFilePaths.flatMap(readCSVsFrom7z)
  }
}

第三步:测试代码

现在你可以直接调用工具类,处理你的abc.7z和xyz.7z文件:

object Main extends App {
  // 传入你的两个7z文件路径
  val target7zFiles = List("abc.7z", "xyz.7z")
  val allCsvData = SevenZCSVReader.readCSVsFromMultiple7Zs(target7zFiles)

  // 示例:打印第一个CSV文件的前3行内容
  allCsvData.head.take(3).foreach(row => println(row.mkString(",")))
}

关键细节提示

  • 资源释放:所有IO流都要在使用后关闭,代码里用finally块确保SevenZFile不会泄漏资源。
  • 异常处理:实际项目中建议添加try-catch块捕获IOException(比如文件不存在、7z格式损坏等情况),避免程序崩溃。
  • 大数据场景:如果你的CSV文件体积很大,推荐结合Spark处理,只需额外配置7z编解码器即可实现分布式读取,但上面的方案更适合小到中等规模的文件。

内容的提问来源于stack exchange,提问作者Nick

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 07:57:14