c - 如何附加到从 libcurl 下载的文件?

标签 c macos libcurl

我知道这看起来很简单,但这是我一直在苦恼的程序中的一个大错误。简而言之,我想让 libcurl 从 FTP 服务器下载文件,将文本附加到该文件,然后将文件上传回服务器。我的问题是,我的程序不是将文本附加到文件,而是覆盖文件的内容,即使当我写入下载的文件时,我在 fopen() 中使用 a+ 文件操作模式。如果有人以前做过类似的事情,我们将不胜感激。下面是相关的 C 代码:

void write_to_database(const char* filename, const char* string_to_write) {
    FILE *file = fopen(filename, "a+");
    if (file) {
        printf("Current position in file: %li\n", ftell(file));
        fputs(string_to_write, file);
        fputs("\n", file);
        fclose(file);
    }
}
…
void perform_database_modification(const char* file_to_write, const char* short_database, const char* addr, const char* msg) {
    strcpy(DATABASE_FILE, file_to_write);
    //strcpy(DESTINATION_MUSIC_FILE, music_file);
    strcpy(REMOTE_URL_HEAD, "");
    strcpy(REMOTE_DATABASE_FILE, short_database);
    strcpy(REMOTE_URL, addr);
    strcpy(message, msg);

    remove(DATABASE_FILE);

    CURL *curl;
    CURLcode res;

    struct FtpFile ftpfile={
        DATABASE_FILE, /* name to store the file as if succesful */
        NULL
    };

    /* In windows, this will init the winsock stuff */
    curl_global_init(CURL_GLOBAL_ALL);

    /* get a curl handle */
    curl = curl_easy_init();
    if(curl) {
        /* specify target */
        curl_easy_setopt(curl, CURLOPT_URL, REMOTE_URL);
        //curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);
        printf("Remote URL: %s\n", REMOTE_URL);

        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, curl_database_write);
        /* Set a pointer to our struct to pass to the callback */
        curl_easy_setopt(curl, CURLOPT_WRITEDATA, &ftpfile);

        curl_easy_setopt(curl, CURLOPT_USERNAME, (char *)loginUser);

        curl_easy_setopt(curl, CURLOPT_PASSWORD, (char *)loginPassword);

        fprintf(stderr, "Using: %s %s\n", loginUser, loginPassword);

        /* Now run off and do what you've been told! */
        fflush(stdout); // Flush the buffers so we see the message immediately.
        res = curl_easy_perform(curl);

        /* Check for errors */
        if (res != CURLE_OK)
        {
            fprintf(stderr, "DWNLD DATAB: curl_easy_perform() failed: %s\n", curl_easy_strerror(res));
            if (strcmp("Remote file not found", curl_easy_strerror(res)) != 0) // We are using this to see if remote file exists,
            {                                                                  // so ignore if the error is about that.
                [SBErrorNotice performSelectorOnMainThread:@selector(showError:) withObject:@(curl_easy_strerror(res)) waitUntilDone:NO]; // Show in main thread b/c NSAlert will complain otherwise.
                errorOccurred = true;
            }
        }

        if(ftpfile.stream)
            fclose(ftpfile.stream); /* close the local file */
    }

    /* always cleanup */
    curl_easy_cleanup(curl);

    /* Now see if the file we downloaded exists. */
    if (file_exists(DATABASE_FILE))
    {
        printf("Database file exists.\n");
        write_to_database(DATABASE_FILE, message);
    } else {
        printf("Music index does not exist. Uploading a blank file...\n");
        create_blank_file(DATABASE_FILE);
        write_to_database(DATABASE_FILE, message);
    }
    //write_to_database(DATABASE_FILE, message);

    curl_global_cleanup();
}

如有任何帮助,我们将不胜感激。

最佳答案

这不是一个真正的答案,但它太长了,无法放入评论中。

我只是写了这个小程序来测试原理:

#include <stdio.h>

void append_string_to_file(const char *filename, const char *string)
{
    FILE *f = fopen(filename, "a+");
    if (f)
    {
        printf("Appending string to file %s\n", filename);
        fputs(string, f);
        fclose(f);
    }
}


int main(int argc, char **argv)
{
    int i;
    for(i = 1; i < argc; i++)
    {
         append_string_to_file(argv[i], "This string is added to end of file...\n");
    }
    return 0;
}

在我的测试中,它的表现完全符合预期。由于使用 CURL 不太可能影响“stdio.h”函数正确运行的能力,因此我认为您需要拆开代码并查看哪一部分出了问题。例如,文件中是否有某些特殊字符会导致出现问题(例如 Windows 文本文件中的 CTRL-Z)?

此外,您可以在系统中的示例文件上尝试上述代码,看看是否有效。如果它有效,那么人们可以期望您发布的代码也有效......

关于c - 如何附加到从 libcurl 下载的文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17500807/

相关文章:

c - 为什么在写入使用字符串初始化的 "char *s"时会出现段错误,而不是 "char s[]"?

macos - 如何将 AppleScript 脚本返回列表中的值分配给 Automator 中的变量?

swift - 是否可以在 NSTextField 中逐行更改颜色?

excel - 是否有 Application.GetOpenFilename 的 Mac/PC 变体?

linux - Curl 无法在实时服务器上使用 http/socks 代理

IOS 获取代理设置

c++ - OpenGL:纹理加载但未应用

c - 如何更改变量的类型

python - 加速 cython 代码

c++ - Windows Xp - 无法找到入口点 gettickcount64 kernel32.dll