You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 09:34:55