如何在Squirrel-lang中遍历目录内容?多线程统计文件求助
Squirrel-lang 目录遍历与C API嵌入方案
一、纯Squirrel实现目录遍历(类UNIX系统)
Squirrel标准IO库对目录操作的原生支持有限,但可以通过两种方式实现:
1. 利用readdir方法(部分版本支持)
如果你的Squirrel版本包含目录读取支持,可直接打开目录后循环读取条目:
function traverseDirectory(path) { let fileCount = 0 const dir = file(path, "r") if (!dir) return 0 let entry while ((entry = dir.readdir()) != null) { if (entry == "." || entry == "..") continue const fullPath = path + "/" + entry // 尝试打开判断是否为目录 const testDir = file(fullPath, "r") if (testDir) { fileCount += traverseDirectory(fullPath) testDir.close() } else { fileCount += 1 } } dir.close() return fileCount } // 调用示例 const totalFiles = traverseDirectory(".") print("Total files: " + totalFiles)
注意:部分旧版Squirrel可能没有readdir方法,此时换用下面的系统命令方案。
2. 借助类UNIX系统命令
通过os.execute调用find命令快速统计文件数,适合快速完成作业需求:
function countFiles(path) { const cmd = `find ${path} -type f | wc -l` const result = os.execute(cmd) return parseInt(result) }
此方法依赖系统环境,但实现简单、可靠。
二、通过Squirrel C API嵌入C/C++实现目录遍历
如果纯Squirrel方案行不通,嵌入C代码是更稳定的选择,步骤如下:
1. 编写C/C++目录统计函数
实现递归遍历目录的逻辑:
#include <squirrel.h> #include <dirent.h> #include <string.h> #include <stdio.h> SQInteger count_files(HSQUIRRELVM v) { const SQChar* path; sq_getstring(v, 2, &path); int fileCount = 0; DIR* dir = opendir(path); if (!dir) { sq_pushinteger(v, 0); return 1; } struct dirent* entry; while ((entry = readdir(dir)) != NULL) { if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) continue; char fullPath[1024]; snprintf(fullPath, sizeof(fullPath), "%s/%s", path, entry->d_name); if (entry->d_type == DT_DIR) { // 递归调用注册到虚拟机的函数 sq_pushroottable(v); sq_pushstring(v, _SC("count_files"), -1); sq_get(v, -2); sq_pushstring(v, fullPath, -1); sq_call(v, 1, SQTrue, SQTrue); SQInteger subCount; sq_getinteger(v, -1, &subCount); fileCount += subCount; sq_pop(v, 2); } else if (entry->d_type == DT_REG) { fileCount++; } } closedir(dir); sq_pushinteger(v, fileCount); return 1; }
2. 注册C函数到Squirrel虚拟机
在初始化虚拟机时,将C函数注册为全局可调用函数:
void register_native_functions(HSQUIRRELVM v) { sq_pushroottable(v); sq_pushstring(v, _SC("count_files"), -1); sq_newclosure(v, count_files, 0); sq_newslot(v, -3, SQFalse); sq_pop(v, 1); }
3. 在Squirrel中调用原生函数
编译嵌入后的程序,直接在Squirrel代码中调用:
const total = count_files(".") print("Total files: " + total)
三、8字母编程语言推荐
如果Squirrel的生态问题让你困扰,符合8字母要求的通用语言可选:
- Assembly:汇编语言,支持多线程,资料丰富,虽然学习曲线陡,但完全满足作业需求。
- 若作业允许灵活调整字母数,JavaScript(10字母)是更优选择:生态完善,多线程支持(Worker API),Node.js的
fs模块可轻松实现目录遍历,资料量远超Squirrel。
内容的提问来源于stack exchange,提问作者Finamore00
相关产品推荐
相关产品推荐

