diff --git a/interfaces/kits/native/trash/src/file_trash_n_exporter.cpp b/interfaces/kits/native/trash/src/file_trash_n_exporter.cpp index c016f0592d95a3bf030e232aef0aa7048bfac353..fa27dabba75f57ed7bd45bfa481fef51feffebc8 100644 --- a/interfaces/kits/native/trash/src/file_trash_n_exporter.cpp +++ b/interfaces/kits/native/trash/src/file_trash_n_exporter.cpp @@ -69,7 +69,7 @@ static string GetTimeSlotFromPath(const string &path) // 获取时间戳目录位置 size_t trashPathWithTimePrefixPos = realFilePathWithTime.find_first_of("/"); if (trashPathWithTimePrefixPos == string::npos) { - HILOG_ERROR("GetTimeSlotFromPath: Invalid path = %{public}s", path.c_str()); + HILOG_ERROR("GetTimeSlotFromPath: Invalid path"); return ""; } string timeSlot = realFilePathWithTime.substr(0, trashPathWithTimePrefixPos); @@ -84,7 +84,6 @@ static int RecursiveFunc(const string &path, vector &dirents) HILOG_ERROR("Failed to request heap memory."); return ENOMEM; } - HILOG_DEBUG("RecursiveFunc: scandir path = %{public}s", path.c_str()); int num = scandir(path.c_str(), &(pNameList->namelist), FilterFunc, alphasort); if (num < 0) { HILOG_ERROR("RecursiveFunc: Failed to scan dir"); @@ -158,7 +157,6 @@ static napi_value CreateObjectArray(napi_env env, vector result) static string FindSourceFilePath(const string &path) { - HILOG_INFO("FindSourceFilePath: curFilePath = %{public}s", path.c_str()); size_t slashSize = 1; // 获取/trash目录位置 size_t trashPathPrefixPos = path.find(TRASH_PATH); @@ -186,13 +184,12 @@ static string FindSourceFilePath(const string &path) string realFileName = realFilePath.substr(pos + TRASH_SUB_DIR.length() + timeSlot.length() + slashSize); realFilePath = "/" + realFilePathPrefix + realFileName; - HILOG_INFO("FindSourceFilePath: realFilePath After = %{public}s", realFilePath.c_str()); return realFilePath; } -static bool Mkdirs(const string &path, bool isDir, string &newRecoveredPath) +static bool Mkdirs(const string &path, bool isDir) { - HILOG_INFO("Mkdirs: path = %{public}s", path.c_str()); + HILOG_INFO("Mkdirs start"); string recoveredPath = path; string folderName = ""; size_t lastPos = 0; @@ -213,7 +210,7 @@ static bool Mkdirs(const string &path, bool isDir, string &newRecoveredPath) lastPos = i; auto [isExist, ret] = Access(recoveredPath); if (!isExist && !Mkdir(recoveredPath)) { - HILOG_ERROR("Mkdirs fail for %{public}s ", recoveredPath.c_str()); + HILOG_ERROR("Mkdir fails"); return false; } recoveredPath[i] = '/'; @@ -296,16 +293,14 @@ static int MoveFile(const string &srcFile, const string &destFile) static string RecurCheckIfOnlyContentInDir(const string &path, size_t trashWithTimePos, const string &trashWithTimePath) { - HILOG_INFO("RecurCheckIfOnlyContentInDir: path = %{public}s", path.c_str()); + HILOG_INFO("RecurCheckIfOnlyContentInDir start"); size_t slashPos = path.find_last_of("/"); if (slashPos <= trashWithTimePos) { HILOG_DEBUG("RecurCheckIfOnlyContentInDir: slashPos = %{public}zu", slashPos); return trashWithTimePath; } string parentPath = path.substr(0, slashPos); - HILOG_DEBUG("RecurCheckIfOnlyContentInDir: parentPath = %{public}s", parentPath.c_str()); int num = ScanDir(parentPath); - HILOG_DEBUG("RecurCheckIfOnlyContentInDir: num = %{public}d", num); if (num > 1) { // 同一时间戳目录下存在多个删除项,则不论是还原后的删除还是彻底删除,仅需删除该项 HILOG_DEBUG("RecurCheckIfOnlyContentInDir: find other items in current dir"); @@ -314,14 +309,14 @@ static string RecurCheckIfOnlyContentInDir(const string &path, size_t trashWithT // 需要向上一层目录判断 return RecurCheckIfOnlyContentInDir(parentPath, trashWithTimePos, trashWithTimePath); } else { - HILOG_ERROR("RecurCheckIfOnlyContentInDir: invalid path = %{public}s", path.c_str()); + HILOG_ERROR("RecurCheckIfOnlyContentInDir: invalid path"); } return nullptr; } static string GetToDeletePath(const string &toDeletePath, napi_env env) { - HILOG_INFO("GetToDeletePath: toDeletePath = %{public}s", toDeletePath.c_str()); + HILOG_INFO("GetToDeletePath start"); // 判断是否为有效回收站路径 size_t slashSize = 1; // 获取/Trash目录位置 @@ -467,22 +462,12 @@ static napi_value RecoverFile(napi_env env, const string &filePath) return NVal::CreateUndefined(env).val_; } -static int RecoverFilePart(vector filePathList, map dirPath2UpdatedNameMap) +static int RecoverFilePart(vector filePathList) { // 处理文件 for (size_t j = 0; j < filePathList.size(); j++) { string filePath = filePathList[j]; - HILOG_INFO("RecoverFilePart: filePath = %{public}s", filePath.c_str()); string sourceFilePath = FindSourceFilePath(filePath); - HILOG_INFO("RecoverFilePart: sourceFilePath = %{public}s", sourceFilePath.c_str()); - - size_t lastSlashPos = sourceFilePath.find_last_of("/"); - string fileName = sourceFilePath.substr(lastSlashPos + 1); - string sourceFilePathOnly = sourceFilePath.substr(0, lastSlashPos); - map::iterator iter = dirPath2UpdatedNameMap.find(sourceFilePathOnly); - if (iter != dirPath2UpdatedNameMap.end()) { - sourceFilePath = iter->second + "/" + fileName; - } int moveRet = MoveFile(filePath, sourceFilePath); if (moveRet != ERRNO_NOERR) { return moveRet; @@ -491,35 +476,19 @@ static int RecoverFilePart(vector filePathList, map dirP return ERRNO_NOERR; } -static map MakeAndFindUpdateNameDir(vector filterDirPathList) -{ - map dirPath2UpdatedNameMap; - for (size_t j = 0; j < filterDirPathList.size(); j++) { - string dirPath = filterDirPathList[j]; - string sourceFilePath = FindSourceFilePath(dirPath); - HILOG_DEBUG("MakeAndFindUpdateNameDir: sourceFilePath = %{public}s", sourceFilePath.c_str()); - string newDestPath = sourceFilePath; - if (Mkdirs(sourceFilePath, true, newDestPath)) { - HILOG_DEBUG("MakeAndFindUpdateNameDir: newDestPath = %{public}s", newDestPath.c_str()); - if (newDestPath != sourceFilePath) { - dirPath2UpdatedNameMap.insert(make_pair(sourceFilePath, newDestPath)); - } - } - } - return dirPath2UpdatedNameMap; -} - static napi_value RecoverDir(napi_env env, const string &dirPath) { vector dirents; unique_ptr pNameList = { new (nothrow) struct NameListArg, Deleter }; if (!pNameList) { HILOG_ERROR("RecoverDir: Failed to request heap memory."); + NError(ENOMEM).ThrowErr(env); return nullptr; } int ret = RecursiveFunc(dirPath, dirents); if (ret != ERRNO_NOERR) { HILOG_ERROR("RecoverDir: Failed to Recursive Dir."); + NError(ret).ThrowErr(env); return nullptr; } dirents.emplace_back(dirPath); @@ -536,17 +505,39 @@ static napi_value RecoverDir(napi_env env, const string &dirPath) } } - // 新建目录并获取因为存在同名目录修改过名称的目录 - map dirPath2UpdatedNameMap = MakeAndFindUpdateNameDir(dirPathList); + // 记录还原前目录时间 + map> dir2Times; + + // 新建目录 + for (size_t j = 0; j < dirPathList.size(); j++) { + string sourceFilePath = FindSourceFilePath(dirPathList[j]); + // 获取还原前目录时间 + auto[atime, mtime, retGetTime] = GetFileTime(dirPathList[j]); + if (!Mkdirs(sourceFilePath, true)) { + HILOG_ERROR("RecoverDir: NO valid dirs found"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + // 修改还原后目录时间 + if (retGetTime == ERRNO_NOERR) { + dir2Times.insert(make_pair(sourceFilePath, make_tuple(atime, mtime))); + } + } // 处理文件部分 - auto retRecoveFilePart = RecoverFilePart(filePathList, dirPath2UpdatedNameMap); + auto retRecoveFilePart = RecoverFilePart(filePathList); if (retRecoveFilePart != ERRNO_NOERR) { NError(retRecoveFilePart).ThrowErr(env); HILOG_ERROR("RecoverFilePart: Failed to Recover File in Dir."); return nullptr; } - + + // 更新新增目录时间 + for (auto &item : dir2Times) { + auto [oldAtime, oldMtime] = item.second; + UpdateFileTime(oldAtime, oldMtime, item.first); + } + // 删除目录 auto err = RmDirent(GetToDeletePath(dirPath, env)); if (err) { @@ -579,7 +570,6 @@ napi_value FileTrashNExporter::Recover(napi_env env, napi_callback_info info) return nullptr; } string uriStr = uriPtr.get(); - HILOG_DEBUG("Recover: uriPtr.get() = %{public}s", uriStr.c_str()); // 获取沙箱目录地址 AppFileService::ModuleFileUri::FileUri fileUri(uriStr); @@ -590,12 +580,11 @@ napi_value FileTrashNExporter::Recover(napi_env env, napi_callback_info info) HILOG_ERROR("Recover: Invalid Path"); return nullptr; } - HILOG_DEBUG("Recover: path = %{public}s", path.c_str()); // 判断是否是回收站路径 if (path.find(TRASH_PATH) == string::npos) { NError(EINVAL).ThrowErr(env); - HILOG_ERROR("Recover: path = %{public}s is not Trash path", path.c_str()); + HILOG_ERROR("Recover: Not Trash path"); return nullptr; } @@ -603,7 +592,7 @@ napi_value FileTrashNExporter::Recover(napi_env env, napi_callback_info info) auto [isExist, ret] = Access(path); if (!isExist) { NError(EINVAL).ThrowErr(env); - HILOG_ERROR("Recover: Path is not exist"); + HILOG_ERROR("Recover: path is not Trash path"); return nullptr; } @@ -648,12 +637,11 @@ napi_value FileTrashNExporter::CompletelyDelete(napi_env env, napi_callback_info HILOG_ERROR("Recover: Invalid Path"); return nullptr; } - HILOG_DEBUG("Recover: path = %{public}s", path.c_str()); // 判断是否是回收站路径 if (path.find(TRASH_PATH) == string::npos) { NError(EINVAL).ThrowErr(env); - HILOG_ERROR("Recover: path = %{public}s is not Trash path", path.c_str()); + HILOG_ERROR("Recover: Not Trash path"); return nullptr; } diff --git a/utils/file_util.h b/utils/file_util.h index 20de00231b023aa7886bf3a109a0227120aa423b..2138e3ed8a4c8167549d2369a79fdda4207d813a 100644 --- a/utils/file_util.h +++ b/utils/file_util.h @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -143,6 +144,33 @@ static bool Mkdir(const string &path) return false; } +static tuple GetFileTime(const string &src) +{ + // 获取源文件时间 + StatEntity statEntity; + if (!GetStat(src, statEntity)) { + HILOG_ERROR("Failed to get file stat."); + return {0, 0, EINVAL}; + } + // 拼接秒数和纳秒数 + uint64_t acTimeLong = static_cast(statEntity.stat_.st_atim.tv_sec * TIME_CONVERT_BASE + + statEntity.stat_.st_atim.tv_nsec); + uint64_t modTimeLong = static_cast(statEntity.stat_.st_mtim.tv_sec * TIME_CONVERT_BASE + + statEntity.stat_.st_mtim.tv_nsec); + double acTime = static_cast(acTimeLong) / TIME_CONVERT_BASE; + double modTime = static_cast(modTimeLong) / TIME_CONVERT_BASE; + + return {acTime, modTime, ERRNO_NOERR}; +} + +static void UpdateFileTime(double acTime, double modTime, const string &dest) +{ + // 设置目标文件时间 + uv_fs_t utime_req; + uv_fs_utime(nullptr, &utime_req, dest.c_str(), acTime, modTime, nullptr); + uv_fs_req_cleanup(&utime_req); +} + static int CopyAndDeleteFile(const string &src, const string &dest) { // 获取源文件时间