我知道这个似乎很简单,但这是我的程序中的一个大错误,我一直在为此苦恼。简单地说,我想让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();
}
任何帮助将不胜感激。
答案 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)?
此外,您可以在系统中的示例文件上尝试上述代码,看看是否有效。如果它有效,那么可以预期你发布的代码也可以......