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

如何用libcurl操作远程服务器:获取目录文件列表及定时压缩传输

基于FTP/SSH协议的文件传输与管理实现方案

下面针对需求,分别给出FTP和SSH两种协议下的具体实现方案,以及libcurl获取远程目录/文件列表的方法。


FTP协议实现

1. 每日文件传输至当日日期目录

核心步骤:生成当日日期目录名 → 远程创建目录(若不存在)→ 上传文件到该目录。

用libcurl实现的C语言示例:

#include <curl/curl.h>
#include <time.h>
#include <stdio.h>

int main() {
    CURL *curl = curl_easy_init();
    if (!curl) return 1;

    // 生成当日日期字符串(YYYY-MM-DD)
    char dir_name[11];
    time_t now = time(NULL);
    strftime(dir_name, sizeof(dir_name), "%Y-%m-%d", localtime(&now));

    // 构造FTP URL:包含远程目录和要上传的文件名
    char ftp_url[256];
    snprintf(ftp_url, sizeof(ftp_url), "ftp://user:password@your-server.com/remote-base-path/%s/local-file.txt", dir_name);

    // 设置FTP选项:自动创建缺失目录,开启上传模式
    curl_easy_setopt(curl, CURLOPT_URL, ftp_url);
    curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L);
    curl_easy_setopt(curl, CURLOPT_FTP_CREATE_MISSING_DIRS, 1L);

    // 打开本地文件作为上传数据源
    FILE *file = fopen("local-file.txt", "rb");
    if (!file) {
        perror("Failed to open local file");
        curl_easy_cleanup(curl);
        return 1;
    }
    curl_easy_setopt(curl, CURLOPT_READDATA, file);

    // 执行上传
    CURLcode res = curl_easy_perform(curl);
    if (res != CURLE_OK) {
        fprintf(stderr, "Upload failed: %s\n", curl_easy_strerror(res));
    }

    // 清理资源
    fclose(file);
    curl_easy_cleanup(curl);
    return 0;
}

2. 每周压缩7个日目录

FTP协议本身不支持直接执行远程命令,有两种可选方案:

  • 方案一:本地处理后上传:将7个日目录的文件全部下载到本地,压缩为单个包后上传到远程,再删除远程的原7个目录。适合文件量较小的场景,缺点是效率低。
  • 方案二:借助服务器扩展命令:若FTP服务器支持SITE EXEC命令(部分服务器如vsftpd可配置开启),可通过libcurl发送该命令执行远程压缩,示例代码:
// 构造压缩命令,假设要压缩2023-11-10至2023-11-16的目录
char cmd[256];
snprintf(cmd, sizeof(cmd), "SITE EXEC tar -czf 2023-11-16_week.tar.gz 2023-11-10 2023-11-11 2023-11-12 2023-11-13 2023-11-14 2023-11-15 2023-11-16");

curl_easy_setopt(curl, CURLOPT_URL, "ftp://user:password@your-server.com/remote-base-path/");
curl_easy_setopt(curl, CURLOPT_QUOTE, curl_slist_append(NULL, cmd));
CURLcode res = curl_easy_perform(curl);

此方案依赖服务器配置,兼容性较差,优先推荐使用SSH协议实现远程压缩。

3. 获取FTP目录/文件列表

通过libcurl的CURLOPT_DIRLISTONLY选项获取目录列表,示例:

#include <curl/curl.h>
#include <stdio.h>

// 回调函数:接收目录列表内容
size_t list_write_callback(void *ptr, size_t size, size_t nmemb, void *stream) {
    fwrite(ptr, size, nmemb, (FILE*)stream);
    return size * nmemb;
}

int main() {
    CURL *curl = curl_easy_init();
    if (!curl) return 1;

    curl_easy_setopt(curl, CURLOPT_URL, "ftp://user:password@your-server.com/remote-base-path/");
    curl_easy_setopt(curl, CURLOPT_DIRLISTONLY, 1L); // 仅获取目录/文件列表
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, list_write_callback);
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, stdout); // 输出到控制台

    CURLcode res = curl_easy_perform(curl);
    if (res != CURLE_OK) {
        fprintf(stderr, "List failed: %s\n", curl_easy_strerror(res));
    }

    curl_easy_cleanup(curl);
    return 0;
}

SSH协议(SFTP/SCP)实现

SSH协议支持远程命令执行,更适合实现压缩等复杂操作。

1. 每日文件传输至当日日期目录

通过libcurl的SFTP功能实现,步骤与FTP类似,示例:

#include <curl/curl.h>
#include <time.h>
#include <stdio.h>

int main() {
    CURL *curl = curl_easy_init();
    if (!curl) return 1;

    char dir_name[11];
    time_t now = time(NULL);
    strftime(dir_name, sizeof(dir_name), "%Y-%m-%d", localtime(&now));

    char sftp_url[256];
    snprintf(sftp_url, sizeof(sftp_url), "sftp://user:password@your-server.com/remote-base-path/%s/local-file.txt", dir_name);

    curl_easy_setopt(curl, CURLOPT_URL, sftp_url);
    curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L);
    curl_easy_setopt(curl, CURLOPT_FTP_CREATE_MISSING_DIRS, 1L); // SFTP同样支持自动创建目录

    FILE *file = fopen("local-file.txt", "rb");
    if (!file) {
        perror("Failed to open local file");
        curl_easy_cleanup(curl);
        return 1;
    }
    curl_easy_setopt(curl, CURLOPT_READDATA, file);

    CURLcode res = curl_easy_perform(curl);
    if (res != CURLE_OK) {
        fprintf(stderr, "Upload failed: %s\n", curl_easy_strerror(res));
    }

    fclose(file);
    curl_easy_cleanup(curl);
    return 0;
}

2. 每周压缩7个日目录

利用SSH的远程命令执行功能,直接在服务器上完成压缩和清理,示例:

#include <curl/curl.h>
#include <stdio.h>

int main() {
    CURL *curl = curl_easy_init();
    if (!curl) return 1;

    // 构造压缩命令:生成以周日日期命名的压缩包,删除原7个目录
    const char *cmd = "tar -czf 2023-11-16_week.tar.gz 2023-11-10 2023-11-11 2023-11-12 2023-11-13 2023-11-14 2023-11-15 2023-11-16 && rm -rf 2023-11-10 2023-11-11 2023-11-12 2023-11-13 2023-11-14 2023-11-15 2023-11-16";

    curl_easy_setopt(curl, CURLOPT_URL, "sftp://user:password@your-server.com/remote-base-path/");
    curl_easy_setopt(curl, CURLOPT_SSH_CMD, cmd); // 执行SSH命令

    CURLcode res = curl_easy_perform(curl);
    if (res != CURLE_OK) {
        fprintf(stderr, "Command failed: %s\n", curl_easy_strerror(res));
    }

    curl_easy_cleanup(curl);
    return 0;
}

注意:需确保远程服务器安装了tar等工具,且用户有足够权限执行删除命令。

3. 获取SSH(SFTP)目录/文件列表

有两种方式:

方式一:通过SFTP获取目录列表

与FTP类似,使用CURLOPT_DIRLISTONLY:

// 代码结构与FTP列表示例一致,仅URL改为sftp协议即可
curl_easy_setopt(curl, CURLOPT_URL, "sftp://user:password@your-server.com/remote-base-path/");
curl_easy_setopt(curl, CURLOPT_DIRLISTONLY, 1L);
// 其余回调和执行逻辑相同

方式二:执行SSH ls命令获取列表

通过CURLOPT_SSH_CMD执行ls命令,读取输出:

#include <curl/curl.h>
#include <stdio.h>

size_t cmd_output_callback(void *ptr, size_t size, size_t nmemb, void *stream) {
    fwrite(ptr, size, nmemb, (FILE*)stream);
    return size * nmemb;
}

int main() {
    CURL *curl = curl_easy_init();
    if (!curl) return 1;

    curl_easy_setopt(curl, CURLOPT_URL, "sftp://user:password@your-server.com/");
    curl_easy_setopt(curl, CURLOPT_SSH_CMD, "ls -l /remote-base-path/"); // 执行ls命令
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, cmd_output_callback);
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, stdout);

    CURLcode res = curl_easy_perform(curl);
    if (res != CURLE_OK) {
        fprintf(stderr, "Command failed: %s\n", curl_easy_strerror(res));
    }

    curl_easy_cleanup(curl);
    return 0;
}

内容的提问来源于stack exchange,提问作者user22343737

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 07:15:55