You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用PHP CURL通过REST PUT API上传TAR包内指定大文件

嘿,这个需求刚好有高效的解决方案,不用解压整个4GB的tar包,直接定位到file3的位置分段上传就行,咱们一步步来:

解决方案思路

既然已经知道file3在tar包中的起始偏移量和文件长度,我们可以直接操作文件指针跳过前面的无关内容,只读取并上传我们需要的那3GB数据。这样既节省内存(不用加载整个大文件),也避免了解压的额外开销。核心是利用PHP CURL的CURLOPT_READFUNCTION自定义读取逻辑,控制只读取指定范围的内容。

完整代码实现

下面是可直接复用的代码示例,记得替换其中的占位值:

<?php
// 配置参数
$tarFilePath = './your-archive.tar'; // 你的tar文件路径
$startOffset = 123456; // 已知的file3起始索引(字节数)
$file3Size = 3 * 1024 * 1024 * 1024; // file3的长度,3GB
$apiEndpoint = 'https://your-rest-api.com/upload'; // API的PUT端点

// 打开tar文件,定位到file3的起始位置
$fileHandle = fopen($tarFilePath, 'rb');
if (!$fileHandle) {
    die('无法打开tar文件');
}
fseek($fileHandle, $startOffset);

// 自定义读取函数:只读取file3的内容,直到读完指定长度
$bytesReadTotal = 0;
function readPartialFile($ch, $fd, $length) {
    global $bytesReadTotal, $file3Size;
    
    // 计算本次最多能读的字节数:不超过剩余未读长度,也不超过CURL要求的length
    $remainingBytes = $file3Size - $bytesReadTotal;
    $bytesToRead = min($length, $remainingBytes);
    
    if ($bytesToRead <= 0) {
        return ''; // 已经读完所有需要的内容
    }
    
    // 读取数据
    $data = fread($fd, $bytesToRead);
    $bytesReadTotal += strlen($data);
    
    return $data;
}

// 初始化CURL并设置选项
$ch = curl_init($apiEndpoint);
curl_setopt_array($ch, [
    CURLOPT_PUT => true,
    CURLOPT_INFILE => $fileHandle,
    CURLOPT_INFILESIZE => $file3Size, // 告诉API要上传的文件大小
    CURLOPT_READFUNCTION => 'readPartialFile',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_TIMEOUT => 3600, // 大文件上传建议设置足够长的超时(比如1小时)
    CURLOPT_FOLLOWLOCATION => true,
    // 如果API需要认证,添加对应的请求头,比如:
    // CURLOPT_HTTPHEADER => ['Authorization: Bearer your-token-here'],
]);

// 执行上传并处理结果
$response = curl_exec($ch);
if (curl_errno($ch)) {
    echo "上传失败:" . curl_error($ch);
} else {
    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    echo "上传完成!HTTP状态码:$httpCode,响应内容:$response";
}

// 清理资源
curl_close($ch);
fclose($fileHandle);
?>
关键注意事项
  • 参数准确性:一定要确保$startOffset和$file3Size的数值完全正确,否则会上传错误的内容(比如读多了前面的tar头,或者少读了file3的部分内容)。
  • 超时设置:3GB的文件上传需要很长时间,务必调整PHP的max_execution_time(在php.ini或代码中用set_time_limit(0)),同时CURL的CURLOPT_TIMEOUT也要设置足够大。
  • 内存优化:这个方案是流式读取,每次只读取一小段内容到内存,所以不用担心内存溢出的问题,即使是小内存的服务器也能处理。
  • API兼容性:确认你的REST API支持PUT方法接收完整文件,并且能正确处理指定大小的请求体。如果API支持分块上传,也可以基于这个思路拆分成多个PUT请求,但上面的代码是直接上传完整的file3。

内容的提问来源于stack exchange,提问作者Radu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 04:04:19