在lua中递归删除一个文件夹
rmdir in quick-cocos2d-x with lua.
在使用 quick-cocos2d-x 做项目热更新的时候,我需要建立临时文件夹以保存下载的更新包。在更新完成后,我需要删除这些临时文件和文件夹。
cocos2d-x 和 quick-cocos2d-x 都没有提供删除文件夹功能。我做了如下2个尝试:
1. 使用C++
在 cocos2d-x 2.x 中的 AssetsManager 包中提供了一个 CreateDirectory
方法。这个方法可以跨平台支持创建文件夹。在实际项目中运行没有问题。
1bool AssetsManager::createDirectory(const char *path)
2{
3#if (CC_TARGET_PLATFORM != CC_PLATFORM_WIN32)
4 mode_t processMask = umask(0);
5 int ret = mkdir(path, S_IRWXU | S_IRWXG | S_IRWXO);
6 umask(processMask);
7 if (ret != 0 && (errno != EEXIST))
8 {
9 return false;
10 }
11
12 return true;
13#else
14 BOOL ret = CreateDirectoryA(path, NULL);
15if (!ret && ERROR_ALREADY_EXISTS != GetLastError())
16{
17return false;
18}
19 return true;
20#endif
21}
在 cocos2d-x 2.x 的 AssetsManager sample 范例中提供了一个 reset
方法,这个方法使用系统命令递归删除文件夹。
1void UpdateLayer::reset(cocos2d::CCObject *pSender)
2{
3 pProgressLabel->setString(" ");
4
5 // Remove downloaded files
6#if (CC_TARGET_PLATFORM != CC_PLATFORM_WIN32)
7 string command = "rm -r ";
8 // Path may include space.
9 command += "\"" + pathToSave + "\"";
10 system(command.c_str());
11#else
12 string command = "rd /s /q ";
13 // Path may include space.
14 command += "\"" + pathToSave + "\"";
15 system(command.c_str());
16#endif
17 // Delete recorded version codes.
18 getAssetsManager()->deleteVersion();
19
20 createDownloadedDir();
21}
但是,这个 reset
在 ios 模拟器中运行的时候,xcode会报这样的warinng:
The iOS Simulator libSystem was initialized out of order. This is most often caused by running host executables or inserting host dylibs. In the future, this will cause an abort.
因此,我转而考虑另一个方案。
2. 纯lua
纯 lua 其实是个噱头。这里还是要依赖 lfs(lua file sytem),好在 quick-cocos2d-x 已经包含了这个库。
lfs.rmdir
命令 和 os.remove
命令一样,只能删除空文件夹。因此实现类似 rm -rf
的功能, 必须要递归删除文件夹中所有的文件和子文件夹。
让我们扩展一下 os 包。
1require("lfs")
2
3function os.exists(path)
4 return CCFileUtils:sharedFileUtils():isFileExist(path)
5end
6
7function os.mkdir(path)
8 if not os.exists(path) then
9 return lfs.mkdir(path)
10 end
11 return true
12end
13
14function os.rmdir(path)
15 print("os.rmdir:", path)
16 if os.exists(path) then
17 local function _rmdir(path)
18 local iter, dir_obj = lfs.dir(path)
19 while true do
20 local dir = iter(dir_obj)
21 if dir == nil then break end
22 if dir ~= "." and dir ~= ".." then
23 local curDir = path..dir
24 local mode = lfs.attributes(curDir, "mode")
25 if mode == "directory" then
26 _rmdir(curDir.."/")
27 elseif mode == "file" then
28 os.remove(curDir)
29 end
30 end
31 end
32 local succ, des = os.remove(path)
33 if des then print(des) end
34 return succ
35 end
36 _rmdir(path)
37 end
38 return true
39end
上面的代码在 iOS 模拟器和 Android 真机上测试成功。Windows系统、Mac OSX 以及 iOS 真机还没有测试。我测试后会立即更新。
- 文章ID:2129
- 原文作者:zrong
- 原文链接:https://blog.zengrong.net/post/rmdir_in_quick-cocos2d-x_with_lua/
- 版权声明:本作品采用 署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0) 进行许可,非商业转载请注明出处(原文作者,原文链接),商业转载请联系作者获得授权。