如何检查外部存储空间的可用性?

Posted

技术标签:

【中文标题】如何检查外部存储空间的可用性?【英文标题】:How to check availability of space on external storage? 【发布时间】:2011-03-10 22:25:37 【问题描述】:

您如何检查 SD 卡是否已满,以便您的应用程序可以决定它是否可以继续执行其工作,即写入外部存储或通知用户存储空间已用完。

【问题讨论】:

【参考方案1】:

注意新设备上的 StatFs 和 int 溢出

this answer 中的方法在具有大型外部存储的设备上被破坏了。 例如,在我的 Nexus 7 上,它当前返回约 2 GB,而实际上还剩下约 10 GB 的空间。

// DOES NOT WORK CORRECTLY ON DEVICES WITH LARGE STORAGE DUE TO INT OVERFLOW
File externalStorageDir = Environment.getExternalStorageDirectory();
StatFs statFs = new StatFs(externalStorageDirectory.getAbsolutePath());  
int free = (statFs.getAvailableBlocks() * statFs.getBlockSize()) / 1024 / 1024;

StatFs 确实有返回 longgetAvailableBlocksLong()getBlockCountLong() 的替换方法,但问题是它们仅在 API 级别 18 中添加。

改用这个

最简单的方法是使用getFreeSpace() in java.io.File,在 API 级别 9 中添加,返回 long

返回包含这个的分区上的空闲字节数 小路。如果此路径不存在,则返回 0。

因此,要在外部存储(“SD 卡”)上获得可用空间:

File externalStorageDir = Environment.getExternalStorageDirectory();
long free = externalStorageDir.getFreeSpace() / 1024 / 1024;

或者,如果您真的想要使用 StatFs 但需要支持 API 级别

File externalStorageDir = Environment.getExternalStorageDirectory();
StatFs statFs = new StatFs(externalStorageDir.getAbsolutePath());  
long blocks = statFs.getAvailableBlocks();
long free = (blocks * statFs.getBlockSize()) / 1024 / 1024;

【讨论】:

唯一需要指出的是“getFreeSpace()”在文档中也有这个警告:请注意,这可能是一个乐观的高估,不应被视为保证您的应用程序实际上可以写入这么多字节。【参考方案2】:
/******************************************************************************************
Returns size in MegaBytes.

If you need calculate external memory, change this: 
   StatFs statFs = new StatFs(Environment.getRootDirectory().getAbsolutePath());
to this: 
   StatFs statFs = new StatFs(Environment.getExternalStorageDirectory().getAbsolutePath());

******************************************************************************************/
    public long totalMemory()
    
        StatFs statFs = new StatFs(Environment.getRootDirectory().getAbsolutePath());   
        long   total  = (statFs.getBlockCount() * statFs.getBlockSize()) / 1048576;
        return total;
    

    public long freeMemory()
    
        StatFs statFs = new StatFs(Environment.getRootDirectory().getAbsolutePath());
        long   free   = (statFs.getAvailableBlocks() * statFs.getBlockSize()) / 1048576;
        return free;
    

    public long busyMemory()
    
        StatFs statFs = new StatFs(Environment.getRootDirectory().getAbsolutePath());   
        long   total  = (statFs.getBlockCount() * statFs.getBlockSize()) / 1048576;
        long   free   = (statFs.getAvailableBlocks() * statFs.getBlockSize()) / 1048576;
        long   busy   = total - free;
        return busy;
    

【讨论】:

如果您有很多存储空间,您可能希望将那些 ints 更改为 long @ZachRattner 的观点非常好。 注意:如果您只是复制粘贴上面的代码,则结果在较新的设备上会错误(例如 1872 MB 而不是 10064 MB)。 See this answer for a reliable alternative.【参考方案3】:

使用StatFs并将外部存储目录的路径传递给构造函数,就可以在StatFs对象上调用getAvailableBlocks()getBlockSize()等函数。

【讨论】:

这个答案使用 Formatter.formatFileSize - 比除以 1048576 更好。***.com/a/4595449/425050【参考方案4】:

我认为您可以使用此语句来解​​决您的问题。这不能检查sdcard是否有足够的容量。

if(android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED))
    //to do something in here

【讨论】:

嗨黄,谢谢。那只会告诉我媒体是否安装了读/写访问权限。我想知道媒体是否已满。有什么想法吗?【参考方案5】:
/**
 * @return Number of bytes available on external storage
 */
public static long getExternalStorageAvailableSpace() 
    long availableSpace = -1L;
    try 
        StatFs stat = new StatFs(Environment.getExternalStorageDirectory()
                .getPath());
        stat.restat(Environment.getExternalStorageDirectory().getPath());
        availableSpace = (long) stat.getAvailableBlocks() * (long) stat.getBlockSize();
     catch (Exception e) 
        e.printStackTrace();
    

    return availableSpace;

【讨论】:

【参考方案6】:

以下是获取内部存储大小的方法:

 StatFs statFs = new StatFs(Environment.getRootDirectory().getAbsolutePath());        
 long blockSize = statFs.getBlockSize();
 long totalSize = statFs.getBlockCount()*blockSize;
 long availableSize = statFs.getAvailableBlocks()*blockSize;
 long freeSize = statFs.getFreeBlocks()*blockSize;

以下是获取外部存储大小(SD 卡大小)的方法:

 StatFs statFs = new StatFs(Environment.getExternalStorageDirectory().getAbsolutePath());        
 long blockSize = statFs.getBlockSize();
 long totalSize = statFs.getBlockCount()*blockSize;
 long availableSize = statFs.getAvailableBlocks()*blockSize;
 long freeSize = statFs.getFreeBlocks()*blockSize;

【讨论】:

以上是关于如何检查外部存储空间的可用性?的主要内容,如果未能解决你的问题,请参考以下文章

Android存储及getCacheDir()getFilesDir()getExternalFilesDir()getExternalCacheDir()区别

获取 Android 上的所有总空间和可用空间

安卓手机提示没有可用的外部存储,怎么办?

Android14.2 外部文件存储和读取

错误记录Android 分区存储下的 SD 卡应用专属外部存储空间目录访问 ( 需手动创建应用专属外部存储空间目录 )

错误记录Android 分区存储下的 SD 卡应用专属外部存储空间目录访问 ( 需手动创建应用专属外部存储空间目录 )