如何通过NextCloud共享链接上传超1GB的大文件?
通过NextCloud共享链接分块上传大文件(Shell/Python实现)
核心思路
NextCloud共享链接的WebDAV端点(/public.php/webdav/)兼容OwnCloud的分块上传逻辑,只需将分块文件按特定格式命名上传,最后触发合并即可,无需依赖用户专属的上传目录。
前置条件
- 共享链接已启用上传权限
- 掌握共享链接末尾的
share_token(作为WebDAV用户名),以及共享密码(若有设置) - 本地安装
curl或Python(带requests库)
Curl实现步骤
1. 初始化参数
# 替换为你的实际信息 TRANSFER_ID=$(uuidgen) # 生成唯一传输ID,避免冲突 FILE_PATH="/path/to/your/large_file.bin" FILE_NAME="large_file.bin" CHUNK_SIZE=$((1024*1024*100)) # 100MB/块,需小于服务器单文件上传限制 SHARE_TOKEN="your_share_token" SHARE_PASSWORD="your_share_password" # 无密码则删除此变量 SERVER="https://your-nextcloud-domain.com" # 计算总块数 FILE_SIZE=$(stat -c%s "$FILE_PATH") CHUNK_COUNT=$(( ($FILE_SIZE + CHUNK_SIZE - 1) / CHUNK_SIZE ))
2. 分块上传
for ((i=0; i<CHUNK_COUNT; i++)); do START=$((i*CHUNK_SIZE)) END=$((START+CHUNK_SIZE-1)) # 处理最后一块的结束位置 if [ $END -ge $FILE_SIZE ]; then END=$((FILE_SIZE-1)) fi # 构造分块文件的上传路径 CHUNK_URL="$SERVER/public.php/webdav/$FILE_NAME-chunking-$TRANSFER_ID-$CHUNK_COUNT-$i" # 执行上传 if [ -z "$SHARE_PASSWORD" ]; then curl -u "$SHARE_TOKEN" \ -H "Content-Range: bytes $START-$END/$FILE_SIZE" \ -X PUT \ --data-binary "@$FILE_PATH" \ "$CHUNK_URL" else curl -u "$SHARE_TOKEN:$SHARE_PASSWORD" \ -H "Content-Range: bytes $START-$END/$FILE_SIZE" \ -X PUT \ --data-binary "@$FILE_PATH" \ "$CHUNK_URL" fi done
3. 触发文件合并
上传完所有分块后,发送合并请求:
MERGE_URL="$SERVER/public.php/webdav/$FILE_NAME" if [ -z "$SHARE_PASSWORD" ]; then curl -u "$SHARE_TOKEN" \ -H "OC-Chunked: $TRANSFER_ID" \ -X PUT \ -d "" \ "$MERGE_URL" else curl -u "$SHARE_TOKEN:$SHARE_PASSWORD" \ -H "OC-Chunked: $TRANSFER_ID" \ -X PUT \ -d "" \ "$MERGE_URL" fi
Python实现示例
import os import uuid import requests # 替换为你的实际信息 share_token = "your_share_token" share_password = "your_share_password" server = "https://your-nextcloud-domain.com" file_path = "/path/to/your/large_file.bin" file_name = "large_file.bin" chunk_size = 100 * 1024 * 1024 # 100MB/块 # 初始化参数 transfer_id = str(uuid.uuid4()) file_size = os.path.getsize(file_path) chunk_count = (file_size + chunk_size - 1) // chunk_size auth = (share_token, share_password) # 分块上传 with open(file_path, "rb") as f: for chunk_idx in range(chunk_count): start = chunk_idx * chunk_size end = min(start + chunk_size - 1, file_size - 1) # 构造请求头和URL headers = {"Content-Range": f"bytes {start}-{end}/{file_size}"} chunk_url = f"{server}/public.php/webdav/{file_name}-chunking-{transfer_id}-{chunk_count}-{chunk_idx}" # 读取分块数据并上传 f.seek(start) chunk_data = f.read(chunk_size) response = requests.put(chunk_url, data=chunk_data, headers=headers, auth=auth) response.raise_for_status() print(f"完成块 {chunk_idx+1}/{chunk_count} 上传") # 触发合并 merge_url = f"{server}/public.php/webdav/{file_name}" headers = {"OC-Chunked": transfer_id} response = requests.put(merge_url, data=b"", headers=headers, auth=auth) response.raise_for_status() print("文件合并完成")
关键说明
- 分块大小必须小于服务器当前的单文件上传限制(管理员不调整的情况下)
transfer_id必须唯一,避免与其他并行上传冲突- 若某块上传失败,只需重新上传对应块即可,无需重复上传全部内容
- 原NextCloud用户专属的
remote.php/dav/uploads/<userid>路径无法用于共享链接,因为共享链接没有用户级权限;而OwnCloud的分块格式适配共享链接的WebDAV端点后可正常工作
内容的提问来源于stack exchange,提问作者olebole
相关产品推荐
相关产品推荐

