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
相关产品推荐
相关产品推荐

