在没有剩余空间的驱动器上出现奇怪的写入文件问题

Ale*_*lev 5 c++ android

我们发现(不同的设备、不同的 Android 版本)当我们在没有剩余空间的 SD 卡上写入时,Android 不会返回错误!

即我能够成功创建一个新文件,并且文件写入函数也返回正常状态,但它实际上没有写入任何内容。该文件在磁盘上的实际大小仍为 0 字节。

我们正在使用本机 C++ API。

我尝试在我的 Android 11 手机上的新项目上重现此问题,是的 - 问题仍然存在。

我执行了以下步骤:

  1. 使用 Android Studio 创建一个新的 Native C++ 项目。
  2. 在其 C++ 代码中添加测试函数并调用它。
  3. 使用 Android Studio 启动项目 - 是的,我们能够看到相同的行为。

我使用的测试代码:

#include <android/log.h>

bool test()
{
    std::srand(std::time(0));

    auto path = "/storage/150E-2D07/Download/test_1";

    FILE *f2 = nullptr;
    bool ok = true;

    std::int64_t bytesWritten = 0;

#define checkok if (!ok) goto _error

    ok = nullptr != (f2 = fopen(path, "wb"));
    checkok;
    ok = ferror(f2) == 0;
    checkok;

    for (int i = 0; ; ++i)
    {
        char a[16*1024];
        for (int i = 0; i < sizeof(a); ++i)
            a[i] = std::rand()%256;

        ok = sizeof(a) == fwrite(a, 1, sizeof(a), f2);
        checkok;

        ok = ferror(f2) == 0;
        checkok;

        ok = !fflush(f2);
        checkok;

        ok = ferror(f2) == 0;
        checkok;

        bytesWritten += sizeof(a);
        if (!(i % 1000))
            __android_log_print(ANDROID_LOG_VERBOSE, "TEST", "writing.. bytes written: %f", bytesWritten/1024.0/1024.0);
    }

    return true;

    _error:
    if (f2)
        fclose(f2);

    return false;
}
Run Code Online (Sandbox Code Playgroud)

我还注意到,当没有剩余空间时,fwrite功能运行得更快(我们获得了 SD 卡无法承受的速度)。

我创建了 Android 13 虚拟设备,其中包含 500MB 模拟 SD 卡。在其中启动了我的测试应用程序。它写入了 1.4GB 的数据,然后我终止了它。我将此文件复制到我的计算机上,发现第一个 500MB 充满了实际数据,其余内容只是零。对我来说,这听起来像是 Android 操作系统的一个彻底的错误。我想知道这样一个严重的错误怎么可能仍然存在,而且似乎没有人关心它。

Ale*_*lev 0

我在这里创建了一个错误报告:https://issuetracker.google.com/issues/280236407

有人告诉我我需要打电话fsync。是的,fsync 有帮助并返回错误。

在这种情况下,所有其他文件函数在 Android 下都不会返回任何错误(包括fclose)。