You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Android NDK应用突发全量文件丢失问题排查及代码合理性咨询

让我帮你逐一分析这段代码里的潜在问题,以及可能导致数据突然“消失殆尽”的核心原因:

一、Java层路径获取的可优化点(及潜在风险)

你的SetFilePath函数在获取存储路径的逻辑上有几个值得注意的地方:

  • 异常捕获范围过大:你用catch (Exception e)捕获所有异常,并且日志提示缺少WRITE_EXTERNAL_STORAGE权限,但实际上从Android 10(API 29)开始,访问getExternalFilesDir()返回的应用专属外部存储目录,已经不需要申请这个权限了。这个错误提示可能会误导你排查方向,建议去掉多余的try-catch,直接判断getExternalFilesDir()的返回值是否为null:
    String storageState = Environment.getExternalStorageState();
    if (Environment.MEDIA_MOUNTED.equals(storageState)) {
        File externalDir = getExternalFilesDir(null);
        if (externalDir != null) {
            storagePath = externalDir.getAbsolutePath();
        }
    }
    
  • 路径仅初始化一次?:如果你的SetFilePath只在应用启动时调用一次,那当应用在后台被系统回收重启时,若此时外部存储状态发生变化(比如SD卡被移除),存储路径会切换到内部存储,用户之前存在外部存储的数据就会“看不见”——但这不是数据被删除,只是路径切换了。不过你描述的是“存储路径下无任何内容”,这个可能性需要结合你的启动逻辑排查。
二、C++写文件函数的明显问题

你的WriteFile函数存在完全多余的操作,会增加数据损坏风险:

  • 重复打开清空文件:你先以w+模式打开文件然后立刻关闭,接着又用w+b模式打开。这两种模式都会直接清空目标文件(如果存在),第一次操作完全是画蛇添足,还可能导致:如果第一次打开成功但第二次失败,文件会被清空却没有写入数据,直接造成单文件数据丢失。
  • 未校验写入结果:你没有检查fwrite的返回值,无法确认数据是否完整写入。如果写入过程中出现IO错误,函数会错误地返回true,导致你误以为数据已保存。

优化后的C++函数应该是这样的:

bool WriteFile(char *theFilename, char *theDataPtr, int theLen) { 
    FILE* aFile = fopen(theFilename, "w+b"); 
    if (!aFile) return false; 
    size_t writtenBytes = fwrite(theDataPtr, 1, theLen, aFile); 
    fclose(aFile); 
    // 校验实际写入的字节数是否等于预期长度
    return writtenBytes == static_cast<size_t>(theLen); 
}
三、导致所有数据彻底消失的核心可能原因

需要明确的是:你提供的代码本身不会直接导致整个存储目录的内容被清空,更不会出现“如同应用被彻底卸载”的现象。这种情况大概率是以下外部因素或未展示的代码逻辑导致的:

  • 用户/系统自动清除应用存储:如果用户手动在系统设置里清除了应用的“存储”数据,或者设备的自动清理软件、系统存储优化功能触发了清除操作,getFilesDir()getExternalFilesDir()下的所有内容都会被清空,效果和卸载重装完全一致。
  • 外部存储设备故障:如果你的应用使用了可移除的SD卡作为外部存储,当SD卡被格式化、损坏或意外移除时,getExternalFilesDir()指向的目录会直接消失,此时应用会切换到内部存储,用户自然看不到之前的数据。
  • 未展示的目录删除逻辑:如果你的代码其他部分存在触发删除整个存储目录的逻辑(比如误调用了递归删除函数、执行了rm -rf命令),当某个条件触发时,就会清空所有数据。
  • 应用意外卸载重装:某些设备的自动更新功能、应用保护机制可能会出现异常,导致应用被意外卸载后自动重装,此时存储目录会被系统清空。
总结

先优化代码中那些可能导致单文件损坏的问题,再重点排查外部因素和未展示的代码逻辑——尤其是是否存在误删除目录的操作,以及用户设备的存储清理行为。

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

火山引擎 最新活动