看了一些《SCIP》,最深的体会就是:编程就是不断的提取出共性的东西,做成一个抽象的函数来操作。
例如里面有一个概念叫做高阶函数(higher-order procedures),
其实就是把函数当成数据来操作。
这些在C/C++里面也经常用到,比如Sort一个list时,会传递进去一个比较大小的函数
例如Sort(list[], n, void (*cmp)(void*, void*))
最近写一个模块,里面有小一部分需要对目录进行操作:
1. 打印某个目录下所有的文件
2. 遍历的删除一个目录(这个是因为Win32的RemoveDirectory()和linux的rmdir()都只能删除空文件)
这两个操作的共性是都需要遍历目录下的文件,所以可以提取成一个函数,
然后在定义各自的操作函数去实现各自的功能就可以了
- typedef void (*FileOperator)(const char* dir_name, void* file_data);
- void TraverseDir(const char* dir_name, FileOperator fop)
- {
- #ifdef _WIN32
- char search_path[MAX_FILE_PATH_LEN];
- snprintf(search_path, MAX_FILE_PATH_LEN, "%s/*", dir_name);
- DWORD err_code = 0;
- WIN32_FIND_DATA find_data;
- HANDLE hOpen = FindFirstFile(search_path, &find_data);
- if (hOpen == INVALID_HANDLE_VALUE)
- {
- err_code = GetLastError();
- printf("FindFirstFile failed, path: %s, error code: %d\n",
- dir_name, err_code);
- }
- while (FindNextFile(hOpen, &find_data))
- {
- if ( (strcmp(find_data.cFileName, ".") == 0) ||
- (strcmp(find_data.cFileName, "..") == 0) )
- continue;
- fop(dir_name, &find_data);
- }
- FindClose(hOpen);
- #else
- struct dirent* pDirEntry = NULL;
- DIR* pDir = opendir(dir_name);
- if (pDir == NULL)
- {
- printf("opendir failed, path: %s, error code: %d\n",
- dir_name, errno);
- }
- while (pDirEntry = readdir(pDir))
- {
- if ( (strcmp(pDirEntry->d_name, ".") == 0) ||
- (strcmp(pDirEntry->d_name, "..") == 0) )
- continue;
- fop(dir_name, pDirEntry, out_data);
- }
- closedir(pDir);
- #endif
- }
然后提取了WIN32和linux平台的共同操作:
- int MyDeleteFile(const char* filename)
- {
- int result = -1;
- #ifdef _WIN32
- DeleteFile(filename))
- result = 0;
- #else
- if (unlink(filename) == 0)
- result = 0;
- #endif
-
- return result;
- }
- int MyDeleteDir(const char* dir_name)
- {
- int result = -1;
- #ifdef _WIN32
- if (RemoveDirectory(dir_name))
- result = 0;
- #else
- if (rmdir(dir_name) == 0)
- result = 0;
- #endif
- return result;
- }
- bool IsDir(void* data)
- {
- bool ret = false;
- #ifdef _WIN32
- WIN32_FIND_DATA* pFindData = (WIN32_FIND_DATA*)data;
- if (pFindData->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
- ret = true;
- #else
- struct dirent* pDirEntry = (struct dirent*)data;
- if (pDirEntry->d_type & DT_DIR)
- ret = true;
- #endif
- return ret;
- }
- char* GetFileName(void* data)
- {
- char* filename = NULL;
- #ifdef _WIN32
- WIN32_FIND_DATA* pFindData = (WIN32_FIND_DATA*)data;
- filename = pFindData->cFileName;
- #else
- struct dirent* pDirEntry = (struct dirent*)data;
- filename = pDirEntry->d_name;
- #endif
- return filename;
- }
最后定义打印和删除操作:
- void PrintOperator(char* dir_name, void* file_data)
- {
- printf("%s/%s, %s", dir_name, GetFileName(file_data),
- IsDir(file_data) ? "dir" : "file")
- }
- uint32_t RmdirOperator(char* dir_name, void* file_data)
- {
- char child_dir_name[MAX_FILE_PATH_LEN];
- snprintf(child_dir_name, MAX_FILE_PATH_LEN, "%s/%s",
- ir_name, GetFileName(in_data));
- if (IsDir(file_data))
- {
- TraverseDir(child_dir_name, FileOperatorRmdir);
- MyDeleteDir(child_dir_name);
- }
- else
- {
- MyDeleteFile(child_dir_name);
- }
- }
- void PrintDir(char* dir)
- {
- TraverseDir(dir, PrintOperator);
- }
- void Rmdir(char* dir)
- {
- TraverseDir(dir, RmdirOperator);
- MyDeleteDir(dir)
- }
阅读(2670) | 评论(0) | 转发(0) |