【问题标题】:android seems not support statfs()android 似乎不支持 statfs()
【发布时间】:2012-05-29 07:22:10
【问题描述】:

我想检查android是否支持系统调用,statfs()。 所以,我做了下面的代码来检查它(它是通过ndk编译的):

#include <sys/vfs.h>
#include <stdio.h>

int main()
{
    struct statfs diskInfo;
    statfs("/data",&diskInfo);
    perror("statfs,/data");
    unsigned long long blocksize = diskInfo.f_bsize;
    unsigned long long totalsize = blocksize * diskInfo.f_blocks;
    printf("new TOTAL_SIZE == %lu MB/n",totalsize>>20);
    unsigned long long freeDisk = diskInfo.f_bfree*blocksize;
    printf("DISK_FREE == %ld MB/n",freeDisk>>20);

 return 0;
}

并且编译时没有报错,但是通过adb在android模拟器中运行时,提示如下:

kaiwii@ubuntu:~$ adb shell /data/pwrite/test2
statfs,/data: No such file or directory
new TOTAL_SIZE == 0 MB/nDISK_FREE == 0 MB/n

有什么想法吗?谢谢

【问题讨论】:

  • 你知道Android提供了Java wrapper for StatFS吗?如果这不符合您的需求,您可能想查看它的实现,尽管它可能只是根据描述包装对 Unix 命令的调用。
  • 是的。但是,我需要使用系统调用本身。
  • 嗯,你确定你的模拟器上有文件或目录/data?如果您尝试仅使用“/”会发生什么?
  • 当然可以。我也尝试了“/”,但它也失败了

标签: android linux android-ndk linux-kernel


【解决方案1】:

其实Android中使用statfs来发现可用空间。正如@MH 指出的那样,起点是StatFs.java 类。您可以在frameworks/base/core/jni/android_os_StatFs.cpp 中找到本机函数的实现。例如,为了获得空闲块,它实现了以下函数:

static jint
android_os_StatFs_getFreeBlocks(JNIEnv *env, jobject thiz)
{
    struct statfs *stat = (struct statfs *)env->GetIntField(thiz, fields.context);
    return stat->f_bfree;
}

因此,问题不在于 Android 不支持 statfs 系统调用,问题出在您的代码中。在我看来,与android_os_StatFs.cpp 中的代码相比,您使用了错误的标题。在android_os_StatFs.cpp 中使用了以下标题:

#if INCLUDE_SYS_MOUNT_FOR_STATFS
#include <sys/mount.h>
#else
#include <sys/statfs.h>
#endif

【讨论】:

  • 你的分析非常好。但是,当我将标题切换到:#include #include 。出现同样的错误。还有什么想法吗?thx
  • 在我看来,您应该使用 而不是
  • 不知道为什么会出现这个错误。但是尝试对diskInfo 使用动态内存分配。在 android_os_StatFs.cpp 他们使用动态分配。
  • 我可以参考哪种方法?我浏览了整个android_os_StatFs.cpp,但找不到它。thx
  • 看看两种设置环境的方法:android_os_StatFs_native_setup 和 android_os_StatFs_native_restat。
【解决方案2】:

我遇到了同样的问题(statfs 返回 0 个可用字节)。我修复了它,用 fstatfs(...) 替换了 statfs(...) 调用。以下代码适用于我(在 Android 4.2 和 5.0 上测试):

#include <sys/statfs.h>

typedef unsigned long long msize;
msize getAvailableDiskSpace() {
    struct statfs data;
    if (fstatfs(NULL, &data) < 0)
        return 0;
    return (msize)data.f_bsize * data.f_bfree;
}

可能您还需要允许访问 mainfest 文件中的内部存储(不确定,我没有检查如果我删除用户权限会发生什么)。

【讨论】:

    猜你喜欢
    • 2012-06-02
    • 2018-03-20
    • 2018-03-10
    • 2020-07-17
    • 1970-01-01
    • 2015-03-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多