@@ -232,27 +232,33 @@ object ArchiveManager {
232232 } catch (_: Exception ) { msgCount }
233233 } else msgCount
234234
235- // Scan attachment directories — 一次 root find 调用统计全部目录(避免 Java walk 逐文件 stat)
236- val attDirs = listOf (" image2" , " voice2" , " video" , " avatar" , " emoji" , " cdn" )
235+ // 附件统计:直接读 file_manifest.json(含全部文件名),不遍历目录
237236 val counts = mutableMapOf<String , Int >()
238237 val sizes = mutableMapOf<String , Long >()
239238 var totalFiles = 0
240239 var totalSize = 0L
241- val statScript = attDirs.joinToString(" " ) { ad ->
242- " p='${dir.absolutePath} /$ad '; if [ -d \" \$ p\" ]; then echo \" $ad \$ (find \" \$ p\" -type f 2>/dev/null | wc -l) \$ (du -sb \" \$ p\" 2>/dev/null | cut -f1)\" ; fi"
243- }
244- val statOut = RootGateways .runQuiet(statScript, 120_000 )
245- for (line in statOut.lines()) {
246- val parts = line.trim().split(" " )
247- if (parts.size < 3 ) continue
248- val ad = parts[0 ]
249- val n = parts[1 ].toIntOrNull() ? : 0
250- val sz = parts[2 ].toLongOrNull() ? : 0L
251- counts[ad] = n
252- sizes[ad] = sz
253- totalFiles + = n
254- totalSize + = sz
255- Log .d(TAG , " readArchiveInfo: $hash /$ad : $n files, ${formatSize(sz)} " )
240+ try {
241+ val manifestFile = File (dir, " file_manifest.json" )
242+ if (manifestFile.exists()) {
243+ val manifest = JSONObject (manifestFile.readText())
244+ val files = manifest.optJSONArray(" files" ) ? : JSONArray ()
245+ for (i in 0 until files.length()) {
246+ val f = files.getJSONObject(i)
247+ val rel = f.optString(" path" , " " ).removePrefix(" $hash /" )
248+ val ad = rel.substringBefore(" /" )
249+ if (ad.isBlank()) continue
250+ counts[ad] = (counts[ad] ? : 0 ) + 1
251+ val sz = f.optLong(" size" , 0 )
252+ sizes[ad] = (sizes[ad] ? : 0L ) + sz
253+ totalFiles++
254+ totalSize + = sz
255+ }
256+ Log .d(TAG , " readArchiveInfo: $hash manifest files=$totalFiles size=${formatSize(totalSize)} " )
257+ } else {
258+ Log .d(TAG , " readArchiveInfo: no file_manifest.json for $hash " )
259+ }
260+ } catch (e: Exception ) {
261+ Log .w(TAG , " readArchiveInfo: manifest parse failed: ${e.message} " )
256262 }
257263
258264 return ArchiveInfo (
0 commit comments