IBM Cloud Docs
使用 cURL 进行多部分上传

使用 cURL 进行多部分上传

在本教程中,您将学习如何在 Linux 操作系统上使用 cURL 命令分批上传大文件。 步骤包括在终端窗口中运行拆分,将文件分成几部分,启动上传,上传各个部分,以及完成上传。 此外,本教程使用脚本上传每个文件部分并获取其实体标记(ETag),并生成完成多部分上传操作所需的XML块。

场景

大多数工具,如 CLI 或 IBM Cloud® 控制台,以及大多数兼容库和 SDK,都会以多部分上传的方式自动传输对象。 请参阅 “存储大型物体”了解有关多部分上传操作的详细信息。 在某些情况下,您可能更喜欢使用 cURL 命令进行多部分上传,例如,如果您在只读操作系统中工作,无法安装CLI。

准备工作

在开始上传之前,您需要:

使用 curl 需要对命令行和 IBM Cloud® 有一定程度的熟悉,并从 服务凭证端点参考控制台 中获得必要的信息。

将文件分割为多个部分

对于多部分上传,每个文件部分(最后一部分除外)必须至少为 5 MB。 要将文件分割成不同部分,可以在终端窗口中运行 split。 当您决定如何分割文件时,请记住,多部分上传的最大部分数为10,000( 10k )。

在下面的示例中,split命令使用 -b 选项,值为 100M,文件名为 TESTFILE.iso,前缀为“part-”。

split -b 100M TESTFILE.iso part-

此命令生成指定大小的文件部分,文件名分别为part-aa、part-ab、part-ac,以此类推。

开始上传并获取 UploadID

要启动新的多部分上传,请运行 cURL,向带有查询参数 uploads 的对象发出 POST 请求,这将创建一个新的 UploadId 值。 请将正在上传的物品的每个部分与 UploadID 进行对照。

示例请求

curl -X "POST" "https://s3.private.us-south.cloud-object-storage.appdomain.cloud/mputest/TESTFILE.iso?uploads"
-H "Authorization: bearer $bearertoken"

示例响应

_<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<InitiateMultipartUploadResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
    <Bucket>mputest</Bucket>
    <Key>TESTFILE.iso</Key>
    <UploadId>01000194-8fab-0f08-3c54-d7df03b4a127</UploadId>
</InitiateMultipartUploadResult>_

从回复中记下 UploadID。 在这个例子中,UploadID 的值为 01000194-8fab-0f08-3c54-d7df03b4a127

使用脚本上传零件并生成XML块

接下来,您运行 cURL,为要上传的每个文件部分发出 PUT 请求。 每个部分上传的响应头都包含一个ETag值,您必须将其保存为多部分上传操作最后一步的输入。

您可以使用如下bash脚本,而无需手动上传每个部分。 脚本有两个功能:

  1. 上传零件
  2. 创建XML零件清单,该清单保存在本地 /tmp 目录中

当每个文件部分上传时,脚本从响应头中提取其ETag并将其与零件编号一起保存到一个XML块中,作为最后一步的输入。

示例脚本

#!/usr/bin/env bash
set -euo pipefail

# ─── Configuration ───────────────────────────────────────────────────────────────
# Public endpoint for your bucket
ENDPOINT="$COS endpoint"
BUCKET="$bucket"
KEY="$Filename"
UPLOAD_ID="$uploadID gained from initiation of upload"
ACCESS_TOKEN="$BEARERTOKEN"
PARTS_PREFIX="part-"
MANIFEST="parts_manifest.xml"
# ─────────────────────────────────────────────────────────────────────────────────

# 1) Start a fresh manifest
cat > "$MANIFEST" <<EOF
<?xml version="1.0" encoding="UTF-8"?>
<CompleteMultipartUpload>
EOF

part=1
for f in ${PARTS_PREFIX}*; do
    if [[ ! -r "$f" ]]; then
    echo "ERROR: no files matching ${PARTS_PREFIX}*" >&2
    exit 1
    fi

    echo "Uploading $f as part $part…"

    # 2) PUT the part, capture headers
    hdrfile=$(mktemp)
    http_code=$(
    curl -sS \
      -D "$hdrfile" \
      -o /dev/null \
      -X PUT "${ENDPOINT}/${BUCKET}/${KEY}?partNumber=${part}&uploadId=${UPLOAD_ID}" \
      -H "Authorization: Bearer ${ACCESS_TOKEN}" \
      --data-binary @"${f}" \
      -w '%{http_code}'
    )

    if [[ "$http_code" != "200" ]]; then
    echo "ERROR: HTTP $http_code for part $part" >&2
    sed 's/^/  /' "$hdrfile" >&2
    rm -f "$hdrfile"
    exit 1
    fi

    # 3) Extract clean ETag (strip quotes/carriage returns)
    etag=$(grep -i '^ETag:' "$hdrfile" \
         | cut -d' ' -f2 \
         | tr -d '"\r')
    rm -f "$hdrfile"

    if [[ -z "$etag" ]]; then
    echo "ERROR: no ETag for part $part" >&2
    exit 1
    fi

    echo " → Part $part ETag: $etag"

    # 4) Append a well-formed <Part> block
    printf '  <Part>\n    <PartNumber>%d</PartNumber>\n    <ETag>"%s"</ETag>\n  </Part>\n' \
    "$part" "$etag" >> "$MANIFEST"

    part=$((part + 1))
done

# 5) Close the manifest
echo '</CompleteMultipartUpload>' >> "$MANIFEST"

echo "✔ Manifest generated: $MANIFEST"


## Complete multipart upload {: #curl-multipart-complete step}

When all parts are finished uploading, you complete the upload by sending a request with the `UploadId` and an XML block that lists each part number and its respective Etag value.

示例请求

curl -X POST "https://s3.private.us-south.cloud-object-storage.appdomain.cloud/mputest/TESTFILE.iso?uploadId=01000194-8fab-0f08-3c54-d7df03b4a127"
 -H "Authorization: Bearer $bearertoken" -H "Content-Type: application/xml" --data-binary @parts_manifest.xml

示例响应

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<CompleteMultipartUploadResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
    <Location>http://s3.private.us-south.cloud-object-storage.appdomain.cloud/mputest/TESTFILE.iso</Location>
    <Bucket>mputest</Bucket>
    <Key>TESTFILE.iso</Key>
    <ETag>"1a90419141160aa6713b8d196773345e-94"</ETag>
</CompleteMultipartUploadResult>

后续步骤

如果一切顺利,您会收到文件已成功上传到想要的存储桶的确认信息。 如果遇到错误,请务必清理不完整的多部分上传。 如果未停止未完成的多部分上传,则部分上传会继续使用资源。 请参阅 使用 cURL 获取 语法,以获取或停止不完整的多部分上传。