鸿蒙源码分析(四十八)

hks_file_operator.c文件分析

该文件主要是鸿蒙当中文件的相关函数,主要涉及文件的读写删除,还有文件权限的赋值。以及文件路径读取,文件存在的判断等等相关功能。
文件路径:security_huks\services\huks_standard\huks_service\main\os_dependency\posix\hks_file_operator.c

一、代码分析

获取文件名的函数(指的是全名)
参数魏路径,文件名和带路径的文件全名,以及全名的长度

//获取文件名,参数为路径,一个存放文件名的数组和一个全名数组以及全名长度
static int32_t GetFileName(const char *path, const char *fileName, char *fullFileName, uint32_t fullFileNameLen)
{
    
    
    if (path != NULL) {
    
    
        //检查路径是否为空,不为空将path写进fullFileName,长度strlen(path)
        if (strncpy_s(fullFileName, fullFileNameLen, path, strlen(path)) != EOK) {
    
    
            return HKS_ERROR_INTERNAL_ERROR;
        }
        //判断前一个字母是否为分隔符
        if (path[strlen(path) - 1] != '/') {
    
    
            if (strncat_s(fullFileName, fullFileNameLen, "/", strlen("/")) != EOK) {
    
    
                return HKS_ERROR_INTERNAL_ERROR;
            }
        }
        //在路径字符串的结尾追加字符(在路径最后追加文件名)
        if (strncat_s(fullFileName, fullFileNameLen, fileName, strlen(fileName)) != EOK) {
    
    
            return HKS_ERROR_INTERNAL_ERROR;
        }
    } else {
    
    
        //路径为空的处理
        if (strncpy_s(fullFileName, fullFileNameLen, fileName, strlen(fileName)) != EOK) {
    
    
            return HKS_ERROR_INTERNAL_ERROR;
        }
    }

    return HKS_SUCCESS;
}

文件全名的获取
参数含义同上个函数

//获取文件全名
static int32_t GetFullFileName(const char *path, const char *fileName, char **fullFileName)
{
    
    
    uint32_t nameLen = HKS_MAX_FILE_NAME_LEN;
    char *tmpFileName = (char *)HksMalloc(nameLen);
    if (tmpFileName == NULL) {
    
    
        return HKS_ERROR_MALLOC_FAIL;
    }
    (void)memset_s(tmpFileName, nameLen, 0, nameLen);
	//初始化临时数组
    int32_t ret = GetFileName(path, fileName, tmpFileName, nameLen);
    //调用函数获取文件名
    if (ret != HKS_SUCCESS) {
    
    
        HKS_LOG_E("get full fileName failed");
        HKS_FREE_PTR(tmpFileName);
        return ret;
    }

    *fullFileName = tmpFileName;
    return HKS_SUCCESS;
}

判断文件是否存在
参数简单,为一个文件路径和名字

//判断文件是否存在
static int32_t IsFileExist(const char *fileName)
{
    
    
    if (access(fileName, F_OK) != 0) {
    
    
        return HKS_ERROR_NOT_EXIST;
    }

    return HKS_SUCCESS;
}

文件的读取
读取一个文件,核心为read函数

//文件的读取
static uint32_t FileRead(const char *fileName, uint32_t offset, uint8_t *buf, uint32_t len)
{
    
    
    (void)offset;//定义一个偏置变量
    if (IsFileExist(fileName) != HKS_SUCCESS) {
    
    
        //调用函数看是否存在该文件
        return 0;
    }

    char filePath[PATH_MAX + 1] = {
    
    0};
    (void)realpath(fileName, filePath);
    //读取路径
    if (strstr(filePath, "../") != NULL) {
    
    
        HKS_LOG_E("invalid filePath, path %s", filePath);
        return 0;
    }

    FILE *fp = fopen(filePath, "rb");
    //打开文件,打开方式rb。以二进制文件打开
    if (fp == NULL) {
    
    
        HKS_LOG_E("failed to open file");
        return 0;
        //打开失败
    }

    uint32_t size = fread(buf, 1, len, fp);
    //读取文件size
    if (fclose(fp) < 0) {
    
    
        HKS_LOG_E("failed to close file");
        return 0;
    }

    return size;
}

文件size计算
计算文件尺寸size

//文件尺寸读取计算
static uint32_t FileSize(const char *fileName)
{
    
    
    if (IsFileExist(fileName) != HKS_SUCCESS) {
    
    
        return 0;
    }

    struct stat fileStat;
    (void)memset_s(&fileStat, sizeof(fileStat), 0, sizeof(fileStat));
    //fileStat的初始化
    if (stat(fileName, &fileStat) != 0) {
    
    
        HKS_LOG_E("file stat fail.");
        return 0;
    }

    return fileStat.st_size;
}

文件的写入
文件write过程

//写文件
static int32_t FileWrite(const char *fileName, uint32_t offset, const uint8_t *buf, uint32_t len)
{
    
    
    (void)offset;
    char filePath[PATH_MAX + 1] = {
    
    0};
    if (memcpy_s(filePath, sizeof(filePath) - 1, fileName, strlen(fileName)) != EOK) {
    
    
        return HKS_ERROR_BAD_STATE;
    }
    (void)realpath(fileName, filePath);
    if (strstr(filePath, "../") != NULL) {
    
    
        HKS_LOG_E("invalid filePath, path %s", filePath);
        return HKS_ERROR_INVALID_KEY_FILE;
    }

    /* caller function ensures that the folder exists */
    FILE *fp = fopen(filePath, "wb+");
    if (fp == NULL) {
    
    
        HKS_LOG_E("open file fail");
        return HKS_ERROR_OPEN_FILE_FAIL;
    }

    if (chmod(filePath, S_IRUSR | S_IWUSR) < 0) {
    
    
        //chmod函数来赋予指定权限
        HKS_LOG_E("chmod file fail.");
        fclose(fp);
        return HKS_ERROR_OPEN_FILE_FAIL;
    }

    uint32_t size = fwrite(buf, 1, len, fp);
    //写入信息
    if (size != len) {
    
    
        HKS_LOG_E("write file size fail.");
        fclose(fp);
        return HKS_ERROR_WRITE_FILE_FAIL;
    }

    if (fclose(fp) < 0) {
    
    //关闭文件失败
        HKS_LOG_E("failed to close file");
        return HKS_ERROR_CLOSE_FILE_FAIL;
    }

    return HKS_SUCCESS;
}

文件的删除
参数传递文件名,然后根据传入的文件名,匹配到对应文件,删除文件的软硬链接

//文件的删除
static int32_t FileRemove(const char *fileName)
{
    
    
    int32_t ret = IsFileExist(fileName);
    //检测文件是否存在
    if (ret != HKS_SUCCESS) {
    
    
        return HKS_SUCCESS; /* if file not exist, return ok */
    };

    struct stat tmp;
    if (stat(fileName, &tmp) != 0) {
    
    
        return HKS_ERROR_INTERNAL_ERROR;
    }

    if (S_ISDIR(tmp.st_mode)) {
    
    
        return HKS_ERROR_INVALID_ARGUMENT;
    }

    if ((unlink(fileName) != 0) && (errno != ENOENT)) {
    
    //删除文件链接
        HKS_LOG_E("remove file fail: filename = %s, errno = 0x%x", fileName, errno);
        return HKS_ERROR_REMOVE_FILE_FAIL;
    }

    return HKS_SUCCESS;
}

剩下的一些函数都是hks对于文件基本操作的封装
由于封装后函数功能基本没有改变,所以这里就只列举一部分标注后的封装好的函数。
size计算的hks封装
参数为文件路径和文件名

//文件size的计算hks封装,调用filesize函数执行该功能
uint32_t HksFileSize(const char *path, const char *fileName)
{
    
    
    if (fileName == NULL) {
    
    
        return 0;
    }

    char *fullFileName = NULL;
    int32_t ret = GetFullFileName(path, fileName, &fullFileName);
    //获取文件名
    if (ret != HKS_SUCCESS) {
    
    
        return 0;
    }

    uint32_t size = FileSize(fullFileName);
    //用文件名计算size
    HKS_FREE_PTR(fullFileName);
    //释放文件名的存放空间
    return size;
}

```**以上为该文件中代码的分析和理解,感谢阅读和点赞**

猜你喜欢

转载自blog.csdn.net/m0_46976252/article/details/120117755