HarmonyOS:应用及文件系统空间统计

0 阅读5分钟

一、概述

在系统中,可能出现系统空间不够或者cacheDir等目录受系统配额限制等情况,需要应用开发者关注系统剩余空间,同时控制应用自身占用的空间大小。

二、接口说明

表1 文件系统空间和应用空间统计

模块接口名功能
@ohos.file.storageStatisticsgetCurrentBundleStats获取当前应用的存储空间大小(单位为Byte)。
@ohos.file.storageStatisticsgetFreeSize异步获取内置存储的可用空间大小(单位为Byte)。
说明:从API version 15开始,支持该接口。
@ohos.file.storageStatisticsgetFreeSizeSync同步获取内置存储的可用空间大小(单位为Byte)。
说明:从API version 15开始,支持该接口。
@ohos.file.storageStatisticsgetTotalSize异步获取内置存储的总空间大小(单位为Byte)。
说明:从API version 15开始,支持该接口。
@ohos.file.storageStatisticsgetTotalSizeSync同步获取内置存储的总空间大小(单位为Byte)。
说明:从API version 15开始,支持该接口。
@ohos.file.statvfsgetFreeSize获取指定文件系统的剩余空间大小(单位为Byte)。
@ohos.file.statvfsgetTotalSize获取指定文件系统的总空间大小(单位为Byte)。

表2 应用空间统计

注意 表格中统计路径列涉及的目录均指应用的沙箱路径,查看路径前需要先进入对应的应用沙箱空间 进入沙箱空间需要执行以下命令:

  1. hdc shell。
  2. nsenter -t {pid} -m sh。
BundleStats属性含义统计路径
appSize应用安装文件大小(单位为Byte)应用安装文件保存在以下目录:/data/storage/el1/bundle
cacheSize应用缓存文件大小(单位为Byte)应用的缓存文件保存在以下目录:
/data/storage/el1/base/cache
/data/storage/el1/base/haps/entry/cache
/data/storage/el2/base/cache
/data/storage/el2/base/haps/entry/cache
dataSize应用文件存储大小(除应用安装文件和缓存文件)(单位为Byte)应用文件由本地文件、分布式文件以及数据库文件组成。本地文件保存在以下目录(注意缓存文件目录为以下目录的子目录):
/data/storage/el1/base
/data/storage/el2/base
分布式文件保存在以下目录:
/data/storage/el2/distributedfiles
数据库文件保存在以下目录:
/data/storage/el1/database
/data/storage/el2/database

三、 开发示例

3.1 获取文件系统数据分区剩余空间大小

效果图
在这里插入图片描述

示例代码

getFreeSize 方法源码 在这里插入图片描述

function getFreeSize() {
  statfs.getFreeSize(path, (err: BusinessError, number: number) => {
    // number 单位是字节
    if (err) {
      console.error(`获取文件系统数据分区剩余空间大小 失败, code is ${err.code}, message is ${err.message}`);
    } else {
      let sizeG = number / (1024 * 1024 * 1024) // 转换 GB
      console.info(`获取文件系统数据分区剩余空间大小 成功, size is ${number} 字节 , size = ${sizeG} GB`);
    }
  });
}

3.2 获取当前应用的存储空间大小

效果图
在这里插入图片描述

示例代码

function getStorageStatistics(){
  storageStatistics.getCurrentBundleStats((err: BusinessError, bundleStats: storageStatistics.BundleStats) => {
    if (err) {
      console.error(`获取当前应用的存储空间大小 失败, code is ${err.code}, message is ${err.message}`);
    } else {
      let appSizeM = bundleStats.appSize / (1024 * 1024 ) // 转换 MB
      console.info(`获取当前应用的存储空间大小 成功, appsize is ${bundleStats.appSize} , appSizeM = ${appSizeM}`);
    }
  });
}

3.3 异步获取内置存储的总空间大小

示例代码

getTotalSize方法 源码 在这里插入图片描述

function getTotalSize(){
  storageStatistics.getTotalSize().then((number: number) => {
    console.info(`异步获取内置存储的总空间大小 successfully, number is ${number}`);
  }).catch((err: BusinessError) => {
    console.error(`异步获取内置存储的总空间大小 error, code is ${err.code}, message is ${err.message}`);
  });
}

3.4 同步获取内置存储的总空间大小

效果图
在这里插入图片描述

示例代码

getTotalSizeSync 方法源码 在这里插入图片描述

function getTotalSizeSync() {
  try {
    let number = storageStatistics.getTotalSizeSync();
    console.info(`getTotalSizeSync successfully, number is ${number}`);
  } catch (err) {
    let error: BusinessError = err as BusinessError;
    console.error(`getTotalSizeSync failed with error, code is ${error.code}, message is ${error.message}`);
  }
}

3.5 异步获取内置存储的可用空间大小

示例代码

getFreeSize方法源码 在这里插入图片描述

function getFreeSizeAsync(){
  storageStatistics.getFreeSize().then((number: number) => {
    console.info(`getFreeSize successfully, number is ${number}`);
  }).catch((err: BusinessError) => {
    console.error(`getFreeSize failed with error, code is ${err.code}, message is ${err.message}`);
  });
}

3.6 同步获取内置存储的可用空间大小

示例代码

getFreeSizeSync方法源码 在这里插入图片描述

function getFreeSizeSync(){
  try {
    let number = storageStatistics.getFreeSizeSync();
    console.info(`getFreeSizeSync successfully, number is ${number}`);
  } catch (err) {
    let error: BusinessError = err as BusinessError;
    console.error(`getFreeSizeSync failed with error, code is ${error.code}, message is ${error.message}`);
  }
}

四、示例完整代码

import { statfs, storageStatistics } from '@kit.CoreFileKit';
import { BusinessError } from '@kit.BasicServicesKit';
import { common } from '@kit.AbilityKit';


let context = getContext(this) as common.UIAbilityContext;
let path = context.filesDir;

/**
 * 获取文件系统数据分区剩余空间大小
 */
function getFreeSize() {
  statfs.getFreeSize(path, (err: BusinessError, number: number) => {
    // number 单位是字节
    if (err) {
      console.error(`获取文件系统数据分区剩余空间大小 失败, code is ${err.code}, message is ${err.message}`);
    } else {
      let sizeG = number / (1024 * 1024 * 1024) // 转换 GB
      console.info(`获取文件系统数据分区剩余空间大小 成功, size is ${number} 字节 , size = ${sizeG} GB`);
    }
  });
}

/**
 * 获取当前应用的存储空间大小
 */
function getStorageStatistics() {
  storageStatistics.getCurrentBundleStats((err: BusinessError, bundleStats: storageStatistics.BundleStats) => {
    if (err) {
      console.error(`获取当前应用的存储空间大小 失败, code is ${err.code}, message is ${err.message}`);
    } else {
      let appSizeM = bundleStats.appSize / (1024 * 1024) // 转换 MB
      console.info(`获取当前应用的存储空间大小 成功, appsize is ${bundleStats.appSize} , appSizeM = ${appSizeM}`);
    }
  });
}

/**
 * 异步获取内置存储的总空间大小
 */
function getTotalSize() {
  storageStatistics.getTotalSize().then((number: number) => {
    console.info(`异步获取内置存储的总空间大小 successfully, number is ${number}`);
  }).catch((err: BusinessError) => {
    console.error(`异步获取内置存储的总空间大小 error, code is ${err.code}, message is ${err.message}`);
    //  is not a system application
  });
}

/**
 * 同步获取内置存储的总空间大小
 */
function getTotalSizeSync() {
  try {
    let number = storageStatistics.getTotalSizeSync();
    console.info(`getTotalSizeSync successfully, number is ${number}`);
  } catch (err) {
    let error: BusinessError = err as BusinessError;
    console.error(`getTotalSizeSync failed with error, code is ${error.code}, message is ${error.message}`);
    //  getTotalSizeSync failed with error, code is 202, message is The caller is not a system application
  }
}

/**
 * 异步获取内置存储的可用空间大小
 */
function getFreeSizeAsync() {
  storageStatistics.getFreeSize().then((number: number) => {
    console.info(`getFreeSize successfully, number is ${number}`);
  }).catch((err: BusinessError) => {
    console.error(`getFreeSize failed with error, code is ${err.code}, message is ${err.message}`);
    //  is not a system application
  });
}

/**
 * 同步获取内置存储的可用空间大小
 */
function getFreeSizeSync() {
  try {
    let number = storageStatistics.getFreeSizeSync();
    console.info(`getFreeSizeSync successfully, number is ${number}`);
  } catch (err) {
    let error: BusinessError = err as BusinessError;
    console.error(`getFreeSizeSync failed with error, code is ${error.code}, message is ${error.message}`);
    //  is not a system application
  }
}

@Builder
function BaseButton(btnName: string, eventType: number) {
  Column() {
    Button(btnName)
      .fontColor(Color.Black)
      .fontSize(20)
      .fontWeight(FontWeight.Medium)
      .onClick(() => {
        if (eventType == 1) {
          getFreeSize()
          return
        }
        if (eventType == 2) {
          getStorageStatistics()
          return
        }
        if (eventType == 3) {
          getTotalSize()
          return
        }
        if (eventType == 4) {
          getTotalSizeSync()
          return
        }
        if (eventType == 5) {
          getFreeSizeAsync()
          return
        }

        if (eventType == 6) {
          getFreeSizeSync()
          return
        }
      })
  }
}

@Entry
@Component
struct TeststorageSize {
  @State message: string = '应用及文件系统空间统计';

  build() {
    Column({ space: 10 }) {
      Text(this.message)
        .id('TeststorageSizeHelloWorld')
        .fontSize($r('app.float.page_text_font_20fp'))
        .fontWeight(FontWeight.Bold)
        .margin({ top: 20 })
      BaseButton('获取文件系统数据分区剩余空间大小', 1)
      BaseButton('获取当前应用的存储空间大小', 2)
      BaseButton('异步获取内置存储的总空间大小', 3)
      BaseButton('同步获取内置存储的总空间大小', 4)
      BaseButton('异步获取内置存储的可用空间大小', 5)
      BaseButton('同步获取内置存储的可用空间大小', 6)
    }
    .height('100%')
    .width('100%')
  }
}