我知道这看起来很简单,但这是我一直在苦恼的程序中的一个大错误。简而言之,我想让 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/