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;
}
```**以上为该文件中代码的分析和理解,感谢阅读和点赞**