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

时间:2013-07-06 07:33:13

标签: 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();
}

任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:0)

这不是一个真正的答案,但是这样的评论太长了。

我刚刚编写了这个小程序来测试原理:

#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)?

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