如何用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
相关产品推荐
相关产品推荐

