如何从直链直接下载大文件并上传至Google Cloud Storage
直链文件无本地落盘传输至Google Cloud Storage方案
完全存在无需将MP4文件下载到本地存储、直接从直链传输到Google Cloud Storage(以下简称GCS)存储桶的可行方案,全程通过内存流完成数据中转,单文件最高支持TB级大小,完全适配1GB以上大文件传输需求,不会占用本地磁盘空间。
- 核心实现逻辑
摒弃「下载文件到本地磁盘→从本地磁盘读取文件上传GCS」的传统两步流程,改为边通过HTTP客户端流式拉取源直链的MP4数据块,边将拿到的数据块通过GCS的流式上传接口写入目标存储桶,所有数据块仅在内存中做极短暂缓存,不会写入本地磁盘。 - Ruby环境实现要点(匹配官方SDK使用场景)
- 初始化GCS客户端后,不要调用传入本地文件路径的上传方法,直接调用支持IO流输入的上传接口,创建可写的上传流对象绑定到目标存储桶的对象保存路径。
- 向MP4直链发起HTTP GET请求,开启流式响应模式,禁止一次性将整个响应体加载到内存,逐块读取响应返回的二进制数据段。
- 每读取到16MiB~64MiB大小的数据块,就直接写入GCS上传流,所有数据块读取写入完成后关闭流,等待GCS完成文件校验即可。
- 大文件适配优化
- 直接复用GCS官方Ruby SDK内置的分片可恢复上传能力,无需自行实现分片逻辑,传输过程中出现网络中断时仅需重传失败分片,不需要从头传输整个文件。
- 固定读写块大小即可将整个传输过程的内存占用稳定控制在百MB级别,内存占用不会随文件体积增大而上涨。
- 如果源直链支持Range请求头,可结合GCS并行分片上传能力,多线程同时拉取源文件不同区间的数据块并行上传,进一步提升大文件传输速度。
最小实现代码示例
require "google/cloud/storage" require "net/http" require "uri" # 初始化GCS客户端 storage = Google::Cloud::Storage.new( project_id: "替换为你的GCP项目ID", credentials: "替换为你的服务账号鉴权信息" ) bucket = storage.bucket "替换为你的目标存储桶名称" source_mp4_url = "替换为MP4文件直链地址" target_gcs_path = "替换为文件在存储桶内的保存路径" # 流式传输全程不落地本地磁盘 bucket.create_resource target_gcs_path do |upload_stream| uri = URI.parse(source_mp4_url) Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == "https") do |http| request = Net::HTTP::Get.new uri http.request request do |response| # 按32MiB大小逐块读写,控制内存占用 response.read_body(32 * 1024 * 1024) do |chunk| upload_stream.write chunk end end end end
注意:运行代码的环境需要同时具备MP4源直链的访问权限、GCS服务端点的访问权限;在GCP托管服务(Cloud Run、GCE、GKE等)上运行时,可通过内网访问GCS,进一步降低传输成本、提升传输速度。
内容的提问来源于stack exchange,提问作者sagar verma
相关产品推荐
相关产品推荐

