使用Scala计算S3目录文件总大小出现编译错误求助
Scala计算S3文件夹总大小编译错误排查
问题代码
def getFolderSize(filePath: String): Long = { val objects = s3client.listObjectsWithPrefix(bucket, filePath.replace(s"s3://${bucket_name}/", "")) var size: Long = 0 for (obj <- objects) { size += obj.getSize() } return size }
错误信息
error: value += is not a member of Long Expression does not convert to assignment because:value getSize is not a member of String expansion: size = size.+(obj.<getSize: error>()) size += obj.getSize() ^
错误原因
- 核心问题:
s3client.listObjectsWithPrefix返回的并非S3对象实例集合,而是包含对象键(字符串类型)的结果集。你尝试对字符串类型的obj调用getSize()方法,但String类没有这个方法,这是编译失败的根源。 +=的错误是连锁反应:由于obj.getSize()无法编译,编译器无法解析整个赋值表达式,才抛出了看似和Long类型相关的错误,本质是前面的类型不匹配导致的。
修复方案
AWS S3客户端的listObjectsWithPrefix返回的ObjectListing对象提供了getObjectSummaries()方法,可直接获取包含对象大小等元数据的S3ObjectSummary集合,无需单独请求每个对象的元数据。以下是两种修复写法:
写法1:保持循环风格
def getFolderSize(filePath: String): Long = { val prefix = filePath.replace(s"s3://${bucket_name}/", "") val objectSummaries = s3client.listObjectsWithPrefix(bucket, prefix).getObjectSummaries var totalSize: Long = 0 for (summary <- objectSummaries) { totalSize += summary.getSize } totalSize }
写法2:Scala函数式风格(推荐)
def getFolderSize(filePath: String): Long = { val prefix = filePath.replace(s"s3://${bucket_name}/", "") s3client.listObjectsWithPrefix(bucket, prefix).getObjectSummaries .map(_.getSize) .sum }
说明
S3ObjectSummary的getSize()方法直接返回对象的字节大小,无需额外请求元数据,性能更优。- 函数式写法避免了可变变量
var的使用,更符合Scala的设计理念,代码更简洁易维护。
内容的提问来源于stack exchange,提问作者vvazza
相关产品推荐
相关产品推荐

