列举未完成的分段上传
分段上传可以将大文件分割成片段后上传,除了最后一个片段,每个片段的数据大小为5MB~5GB。本文介绍如何列举未完成的分段上传,即已经用S3_initiate_multipart
初始化,但仍然在进行或者S3_complete_multipart_upload
失败的分段上传。
接口定义:
void S3_list_multipart_uploads(S3BucketContext *bucketContext,
const char *prefix, const char *keymarker,
const char *uploadidmarker,
const char *encodingtype, const char *delimiter,
int maxuploads, S3RequestContext *requestContext,
int timeoutMs,
const S3ListMultipartUploadsHandler *handler,
void *callbackData);
参数:
参数名 | 类型 | 说明 |
---|---|---|
bucketContext | S3BucketContext * | 包含bucket及相关的请求参数 |
prefix | const char * | 如果非NULL,则仅列出拥有以该参数为前缀的key的分段上传 |
keymarker | const char * | 如果非NULL,则和uploadidmarker一起指定了只有排序在其后的分段上传才会被列出 |
uploadidmarker | const char * | 如果非NULL,则和keymarker一起指定了只有排序在其后的分段上传才会被列出 |
encodingtype | const char * | 如果非NULL,则请求服务器以指定方法编码响应 |
delimiter | const char * | 如果非NULL,则用于对key进行分组 |
maxuploads | int | 设置返回的分段上传数的最大数量 |
requestContext | S3RequestContext * | 请求参数,如果为NULL,则立即同步执行请求 |
timeoutMs | int | 如果非0,则是以毫秒为单位的请求超时时间 |
handler | const S3ListMultipartUploadsHandler * | 回调函数 |
callbackData | void * | 回调数据 |
代码示例:
typedef struct list_multiparts_callback_data
{
int isTruncated;
char nextKeyMarker[1024];
char nextUploadIdMarker[1024];
int uploadCount;
int allDetails;
} list_multiparts_callback_data;
static S3Status listMultipartCallback(int isTruncated, const char *nextKeyMarker,
const char *nextUploadIdMarker,
int uploadsCount,
const S3ListMultipartUpload *uploads,
int commonPrefixesCount,
const char **commonPrefixes,
void *callbackData)
{
list_multiparts_callback_data *data =
(list_multiparts_callback_data *)callbackData;
data->isTruncated = isTruncated;
if (nextKeyMarker)
{
snprintf(data->nextKeyMarker, sizeof(data->nextKeyMarker), "%s",
nextKeyMarker);
}
else
{
data->nextKeyMarker[0] = 0;
}
if (nextUploadIdMarker)
{
snprintf(data->nextUploadIdMarker, sizeof(data->nextUploadIdMarker), "%s",
nextUploadIdMarker);
}
else
{
data->nextUploadIdMarker[0] = 0;
}
if (uploadsCount && !data->uploadCount)
{
printListMultipartHeader(data->allDetails);
}
int i;
for (i = 0; i < uploadsCount; i++)
{
const S3ListMultipartUpload *upload = &(uploads[i]);
char timebuf[256];
if (1)
{
time_t t = (time_t)upload->initiated;
strftime(timebuf, sizeof(timebuf), "%Y-%m-%dT%H:%M:%SZ",
gmtime(&t));
printf("\nKey: %s\n", upload->key);
printf("Initiated: %s\n", timebuf);
printf("UploadId: %s\n", upload->uploadId);
if (upload->initiatorId)
{
printf("Initiator ID: %s\n", upload->initiatorId);
}
if (upload->initiatorDisplayName)
{
printf("Initiator Display Name: %s\n", upload->initiatorDisplayName);
}
if (upload->ownerId)
{
printf("Owner ID: %s\n", upload->ownerId);
}
if (upload->ownerDisplayName)
{
printf("Owner Display Name: %s\n", upload->ownerDisplayName);
}
printf("StorageClass: %s\n", upload->storageClass);
}
else
{
time_t t = (time_t)upload->initiated;
strftime(timebuf, sizeof(timebuf), "%Y-%m-%dT%H:%M:%SZ",
gmtime(&t));
printf("%-50s %s %-50s", upload->key, timebuf, upload->uploadId);
if (data->allDetails)
{
printf(" %-34s %-64s %-12s %-64s %-12s",
upload->storageClass,
upload->ownerId ? upload->ownerId : "",
upload->ownerDisplayName ? upload->ownerDisplayName : "",
upload->initiatorId ? upload->initiatorId : "",
upload->initiatorDisplayName ? upload->initiatorDisplayName : "");
}
printf("\n");
}
}
data->uploadCount += uploadsCount;
for (i = 0; i < commonPrefixesCount; i++)
{
printf("\nCommon Prefix: %s\n", commonPrefixes[i]);
}
return S3StatusOK;
}
void printListMultipartHeader(int allDetails)
{
(void)allDetails;
}
void list_multipart_uploads(const char *prefix, const char *keymarker, const char *delimiter,
const char *encodingtype, const char *uploadidmarker, int maxuploads)
{
int allDetails = 0;
S3ListMultipartUploadsHandler listMultipartUploadsHandler =
{
{&responsePropertiesCallback, &responseCompleteCallback},
&listMultipartCallback};
list_multiparts_callback_data data;
memset(&data, 0, sizeof(list_multiparts_callback_data));
if (keymarker != 0)
{
snprintf(data.nextKeyMarker, sizeof(data.nextKeyMarker), "%s",
keymarker);
}
if (uploadidmarker != 0)
{
snprintf(data.nextUploadIdMarker, sizeof(data.nextUploadIdMarker),
"%s", uploadidmarker);
}
data.uploadCount = 0;
data.allDetails = allDetails;
do
{
data.isTruncated = 0;
do
{
S3_list_multipart_uploads(&bucketContext, prefix,
data.nextKeyMarker,
data.nextUploadIdMarker, encodingtype,
delimiter, maxuploads, 0,
0,
&listMultipartUploadsHandler, &data);
} while (S3_status_is_retryable(statusG) && should_retry());
if (statusG != S3StatusOK)
{
break;
}
} while (data.isTruncated &&
(!maxuploads || (data.uploadCount < maxuploads)));
if (statusG == S3StatusOK)
{
if (!data.uploadCount)
{
printListMultipartHeader(data.allDetails);
}
}
else
{
printError();
}
}