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

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

【问题讨论】:

    标签: android android-sdcard android-external-storage


    【解决方案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()等函数。

    【讨论】:

    【解决方案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;
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-11-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-06-03
        • 1970-01-01
        • 2011-06-03
        • 2014-12-18
        相关资源
        最近更新 更多