如何通过libcurl获取FTP服务器当前工作目录并转为字符串?
解决libcurl FTP获取当前工作目录的问题
问题根源
- 手动通过
CURLOPT_QUOTE执行CWD/PWD时,libcurl不会自动捕获PWD返回的257响应内容,也不会更新内部维护的工作目录状态(这就是日志中remembering we are in dir ""的原因)。 WRITEFUNCTION仅处理数据连接的内容,而PWD的响应属于控制连接的头信息,因此无法通过该回调获取路径。CURLINFO_EFFECTIVE_URL返回的是初始请求URL,不会跟踪手动执行CWD后的目录变化。
解决方案一:通过HEADER回调捕获PWD响应
利用CURLOPT_HEADERFUNCTION回调捕获控制连接的响应头,从中提取257行中的目录路径:
步骤1:定义数据结构体与回调函数
#include <string.h> #include <stdio.h> #include <curl/curl.h> // 用于保存捕获的目录路径 typedef struct { char dir[256]; } DirData; // 响应头回调函数,提取257响应中的目录 size_t header_callback(char *buffer, size_t size, size_t nitems, void *userdata) { size_t total_len = size * nitems; DirData *data = (DirData *)userdata; // 匹配257响应行 char *found = strstr(buffer, "257 "); if (found) { // 提取引号包裹的路径 char *start_quote = strchr(found, '"'); char *end_quote = strchr(start_quote + 1, '"'); if (start_quote && end_quote) { size_t path_len = end_quote - start_quote - 1; if (path_len < sizeof(data->dir) - 1) { strncpy(data->dir, start_quote + 1, path_len); data->dir[path_len] = '\0'; } } } return total_len; }
步骤2:修改主逻辑代码
int main() { curl_global_init(CURL_GLOBAL_DEFAULT); CURL *curl = curl_easy_init(); if (curl) { DirData dir_data = {0}; // 设置FTP服务器地址 curl_easy_setopt(curl, CURLOPT_URL, "ftp://localhost/"); // 执行CWD切换到foo目录 struct curl_slist *cwd_cmd = curl_slist_append(NULL, "cwd foo"); curl_easy_setopt(curl, CURLOPT_QUOTE, cwd_cmd); curl_easy_perform(curl); curl_slist_free_all(cwd_cmd); // 清除之前的QUOTE命令,设置HEADER回调 curl_easy_setopt(curl, CURLOPT_QUOTE, NULL); curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, header_callback); curl_easy_setopt(curl, CURLOPT_HEADERDATA, &dir_data); // 执行PWD命令获取当前目录 struct curl_slist *pwd_cmd = curl_slist_append(NULL, "pwd"); curl_easy_setopt(curl, CURLOPT_QUOTE, pwd_cmd); curl_easy_perform(curl); curl_slist_free_all(pwd_cmd); // 输出结果 printf("当前工作目录:%s\n", dir_data.dir); curl_easy_cleanup(curl); } curl_global_cleanup(); return 0; }
解决方案二:让libcurl自动管理工作目录
如果不需要手动执行CWD命令,直接通过URL指定路径或使用CURLOPT_PATH,libcurl会自动处理目录切换并维护内部状态:
int main() { curl_global_init(CURL_GLOBAL_DEFAULT); CURL *curl = curl_easy_init(); if (curl) { // 直接在URL中指定目标目录 curl_easy_setopt(curl, CURLOPT_URL, "ftp://localhost/foo/"); // 发送空请求(仅验证目录切换) curl_easy_setopt(curl, CURLOPT_NOBODY, 1); curl_easy_perform(curl); // 此时libcurl内部已记录当前目录为/foo,日志中也会显示正确路径 curl_easy_cleanup(curl); } curl_global_cleanup(); return 0; }
内容的提问来源于stack exchange,提问作者user21296249
相关产品推荐
相关产品推荐

