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

如何以原始文件形式(非流/Buffer/base64)上传至Azure Blob存储

直接上传原始文件到Azure Blob Storage(无需base64/Buffer额外转换)

你完全不需要把文件转成base64来上传——Azure Storage SDK本身就支持直接上传原始文件流或File对象,这样既高效又能避免不必要的编码开销。我来帮你优化代码,实现直接上传原始文件的需求:

问题分析

你当前的代码把文件Buffer转成了base64字符串再上传,这其实是多此一举的操作。BlockBlobClient.upload()方法本身就支持直接接收Buffer、Readable Stream或者浏览器环境的File对象,直接上传原始数据会更高效。

另外,你的代码里还有一个小问题:main()是async函数,但你直接调用它却没有用await处理Promise,这可能会导致未捕获的错误,需要同步修正。

解决方案

场景1:Node.js环境上传本地文件

如果是在Node.js里上传本地的png/jpeg文件,你可以直接用文件流上传,不需要读成Buffer再转base64:

const { BlobServiceClient } = require("@azure/storage-blob");
const fs = require("fs");
const path = require("path");

const blobServiceClient = new BlobServiceClient(
  `https://${account}.blob.core.windows.net`,
  sharedKeyCredential, // 或者你的defaultAzureCredentials
);

// 改进后的上传函数,支持直接上传本地文件路径
async function createBlobFromLocalFile(blobName, localFilePath) {
  try {
    const containerClient = blobServiceClient.getContainerClient('blue');
    const blockBlobClient = containerClient.getBlockBlobClient(blobName);
    
    // 直接创建文件读取流上传
    const fileStream = fs.createReadStream(localFilePath);
    const fileSize = fs.statSync(localFilePath).size;
    
    const uploadBlobResponse = await blockBlobClient.uploadStream(
      fileStream,
      undefined, // 使用默认块大小
      undefined, // 使用默认并发数
      { blobHTTPHeaders: { blobContentType: path.extname(localFilePath).slice(1) } } // 设置正确的MIME类型
    );
    
    console.log(`Upload block blob ${blobName} successfully`, uploadBlobResponse.requestId);
    return uploadBlobResponse.requestId;
  } catch (err) {
    console.error("Upload failed:", err);
    throw err; // 抛出错误让调用方统一处理
  }
}

// 使用示例:上传本地的test.png
createBlobFromLocalFile("test.png", "./test.png")
  .then(requestId => console.log("Request ID:", requestId))
  .catch(err => console.error(err));

场景2:处理前端传来的File对象(比如Express上传)

如果你的代码是在后端接收前端上传的File对象(比如通过multer或者直接读取req.files),可以直接用File的Buffer或者stream上传:

// 假设你在Express中,用multer接收了上传的文件,req.file就是上传的File对象
async function createBlobFromUploadedFile(blobName, uploadedFile) {
  try {
    const containerClient = blobServiceClient.getContainerClient('blue');
    const blockBlobClient = containerClient.getBlockBlobClient(blobName);
    
    // 直接上传文件的Buffer,无需转base64
    const uploadBlobResponse = await blockBlobClient.upload(
      uploadedFile.buffer,
      uploadedFile.size,
      { blobHTTPHeaders: { blobContentType: uploadedFile.mimetype } } // 保留原始MIME类型
    );
    
    console.log(`Upload block blob ${blobName} successfully`, uploadBlobResponse.requestId);
    return uploadBlobResponse.requestId;
  } catch (err) {
    console.error("Upload failed:", err);
    throw err;
  }
}

// 使用示例(Express + multer)
app.post('/upload', upload.single('image'), async (req, res) => {
  try {
    const requestId = await createBlobFromUploadedFile(req.file.originalname, req.file);
    res.status(200).json({ success: true, requestId });
  } catch (err) {
    res.status(500).json({ success: false, error: err.message });
  }
});

关键要点

  • 不要转base64:直接用原始的Buffer或Stream上传,减少内存占用和编码时间
  • 设置正确的Content-Type:上传时指定blobContentType,这样Blob存储的文件会保留正确的MIME类型,下载或访问时浏览器能正确识别
  • 正确处理async/await:确保所有异步操作都用await,避免Promise未处理的问题

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 13:07:29