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

Android API31下Kotlin写入ByteArray到U盘文件为空问题求助

问题分析与解决方案

核心问题定位

  1. 写入逻辑分支错误:原代码中将写入操作包裹在if (!myDir.exists())分支内,仅当目录首次创建时才执行写入,后续运行因目录已存在直接跳过写入步骤,导致文件为空。
  2. 外接存储缓存未同步:Android对外接U盘的写入存在缓存机制,若未强制同步,数据可能仅停留在内存缓存中,未实际写入物理介质。
  3. 异常捕获不完整:原代码仅捕获了目录创建的异常,写入过程的潜在错误未被捕获,无法排查隐式问题。

修复代码示例

fun writeToUsb(storageVolume: StorageVolume) {
    when(storageVolume.state) {
        Environment.MEDIA_MOUNTED -> {
            val rootDir = storageVolume.directory ?: return // 判空避免空指针异常
            val myDir = File(rootDir, "errors")
            
            // 确保目录存在,mkdirs()在目录已存在时返回false但不报错
            if (!myDir.exists() && !myDir.mkdirs()) {
                Log.e("DirError", "创建目录失败: ${myDir.path}")
                return
            }

            val dataToWrite = "FooBar".toByteArray()
            val file = File(myDir, "errorlog.txt")
            
            // 使用try-with-resources自动管理流资源,避免泄漏
            runCatching {
                FileOutputStream(file).use { fos ->
                    fos.write(dataToWrite)
                    fos.flush()
                    file.fsync() // 强制同步缓存到物理U盘(API 26+支持,符合API31要求)
                }
                Log.i("WriteSuccess", "数据写入成功: ${file.path}")
            }.onFailure { e ->
                Log.e("WriteError", "写入文件失败", e) // 打印完整异常栈信息
            }
        }
    }
}

关键修复点说明

  • 调整写入逻辑:将写入操作移出目录判断分支,确保无论目录是否已存在,都执行写入流程。
  • 强制缓存同步:调用file.fsync()强制将内存缓存中的数据刷新到物理U盘,解决内容写入后不显示的问题。
  • 完善异常处理:通过runCatching捕获所有写入相关异常,并打印完整栈信息,快速定位潜在问题。
  • 增加空指针防护:对storageVolume.directory进行判空,避免因存储卷信息异常导致崩溃。

额外注意事项

  • 避免无意义的文件删除-重建操作(如补充测试中的代码逻辑),这种操作会导致文件状态混乱,增加写入失败概率。
  • 确认传入的storageVolume为正确的外接U盘实例,可通过打印storageVolume.directory?.path验证路径是否指向U盘根目录。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 02:15:42