我的应用程序使用libcurl将文件上传到SFTP服务器,有时我需要在当前上传完成之前关闭应用程序。我想中止上传,稍后再继续。但是,当上传中止时,服务器上部分上传文件的末尾会出现损坏的数据。数量各不相同,最多可达10个字节。这使得无法通过附加数据来恢复上传。
请参阅下面的一些示例代码。按Ctrl-C中止上传,然后手动下载部分文件并将其与原始文件进行比较。部分文件的末尾通常会包含不正确的数据。
#include <stdio.h>
#include <signal.h>
#include "curl.h"
// Handle Ctrl-C to abort.
static bool s_bAborted = false;
static void __cdecl ctrlCHandler(int)
{
printf("Aborting...n");
s_bAborted = true;
}
// File reading function.
static size_t readFunction(char * ptr, size_t size, size_t nmemb, void * stream)
{
FILE * pFile = (FILE *)stream;
if (ferror(pFile))
{
return CURL_READFUNC_ABORT;
}
return fread(ptr, size, nmemb, pFile);
}
// Progress function so transfers can be aborted.
static int progressFunction(void * clientp, curl_off_t dltotal, curl_off_t dlnow, curl_off_t ultotal, curl_off_t ulnow)
{
if (s_bAborted)
{
return 1;
}
return CURL_PROGRESSFUNC_CONTINUE;
}
int main()
{
// Add your local file and server URL.
// Note: This problem was observed using an SFTP server.
const char * szLocalFile = "Test.bin";
const char * szRemoteUrl = "sftp://user:password@host/Test.bin";
curl_global_init(CURL_GLOBAL_ALL);
CURL * curl = curl_easy_init();
FILE * pFile = fopen(szLocalFile, "rb");
curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L);
curl_easy_setopt(curl, CURLOPT_URL, szRemoteUrl);
curl_easy_setopt(curl, CURLOPT_READFUNCTION, readFunction);
curl_easy_setopt(curl, CURLOPT_READDATA, pFile);
curl_easy_setopt(curl, CURLOPT_APPEND, 0L);
curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0L);
curl_easy_setopt(curl, CURLOPT_XFERINFOFUNCTION, progressFunction);
printf("Uploading... Press Ctrl-C to abortn");
signal(SIGINT, ctrlCHandler);
CURLcode eResult = curl_easy_perform(curl);
fclose(pFile);
if (eResult == CURLE_OK)
{
printf("Uploaded OKn");
}
else if (eResult == CURLE_ABORTED_BY_CALLBACK)
{
printf("Upload abortedn");
}
else
{
printf("Error: Upload failed: %dn", eResult);
}
curl_easy_cleanup(curl);
curl_global_cleanup();
// After aborting the upload, use something else to download the partial file.
// The last few bytes of the partial file are usually incorrect,
// i.e. different to the original file in that position.
// This makes resuming the upload impossible, since it will append after incorrect bytes.
}
有人能帮忙吗?非常感谢。
根据上面rustyx的建议,我使用read函数将其修改为中止,并删除了进度回调。这似乎解决了问题(在测试了大约15次之后(。
注意:这种方法意味着部分文件总是64kB的倍数。当从进度回调中止时,它是任何随机大小。也许这与此有关。
请参阅下面的更新代码:
#include <stdio.h>
#include <signal.h>
#include "curl.h"
// Handle Ctrl-C to abort.
static bool s_bAborted = false;
static void __cdecl ctrlCHandler(int)
{
s_bAborted = true;
}
// File reading function.
static size_t readFunction(char * ptr, size_t size, size_t nmemb, void * stream)
{
FILE * pFile = (FILE *)stream;
if (s_bAborted || ferror(pFile))
{
return CURL_READFUNC_ABORT;
}
return fread(ptr, size, nmemb, pFile);
}
int main()
{
// Add your local file and server URL.
// Note: This problem was observed using an SFTP server.
const char * szLocalFile = "Test.bin";
const char * szRemoteUrl = "sftp://user:password@host/Test.bin";
curl_global_init(CURL_GLOBAL_ALL);
CURL * curl = curl_easy_init();
FILE * pFile = fopen(szLocalFile, "rb");
curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L);
curl_easy_setopt(curl, CURLOPT_URL, szRemoteUrl);
curl_easy_setopt(curl, CURLOPT_READFUNCTION, readFunction);
curl_easy_setopt(curl, CURLOPT_READDATA, pFile);
curl_easy_setopt(curl, CURLOPT_APPEND, 0L);
printf("Uploading... Press Ctrl-C to abortn");
signal(SIGINT, ctrlCHandler);
CURLcode eResult = curl_easy_perform(curl);
fclose(pFile);
if (eResult == CURLE_OK)
{
printf("Uploaded OKn");
}
else if (eResult == CURLE_ABORTED_BY_CALLBACK)
{
printf("Upload abortedn");
}
else
{
printf("Error: Upload failed: %dn", eResult);
}
curl_easy_cleanup(curl);
curl_global_cleanup();
}