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

为何无法将本地现有文件上传至已有的Azure存储容器?

解决Azure Blob存储上传现有文件无报错但未成功的问题

嘿,我太懂你现在的困扰了——刚上手用C#操作Azure存储,能顺利创建新容器上传新文件,但往已有容器传本地文件时,明明全程没报错,文件却死活出现在容器里。咱们来拆解下问题根源,一步步把它搞定:

核心问题:异步操作没等待(最关键)

你代码里调用的UploadAsync、CreateIfNotExistsAsync、WriteAllTextAsync都是异步方法,但你完全没加await关键字等待它们执行完成。异步方法会立刻返回,程序直接跳到后续代码(比如关闭文件流),这时候上传操作可能还在后台跑,流却被提前切断了,导致上传悄悄失败,还不会抛出异常让你察觉。

次要问题:资源管理不规范

你手动调用uploadFileStream.Close()关闭文件流,这种方式很容易因为代码流程问题导致流未正确关闭。用using语句可以自动管理流的生命周期,确保操作完成后流被正确释放,不用手动操心。

另外,CreateContainerAndUploadFile方法里重复创建了BlobServiceClient,其实可以直接复用类里已经初始化好的成员变量,减少不必要的资源开销。

修改后的完整代码

调整BlobManager类的方法

public class BlobManager {
    private BlobServiceClient blobServiceClient;
    public BlobManager() {
        try {
            string connectionString = ConfigurationManager.AppSettings.Get("StorageConnectionString");
            blobServiceClient = new BlobServiceClient(connectionString);
        } catch (Exception ex) {
            Console.WriteLine($"初始化BlobServiceClient失败:{ex.Message}");
            throw; // 保留抛出异常,但先输出日志方便排查
        }
    }

    // 重命名方法为Async后缀,符合异步方法命名规范
    public async Task UploadFileAsync(string fileName, string container) {
        Console.WriteLine("Entering Upload to existing blob");
        BlobContainerClient containerClient = blobServiceClient.GetBlobContainerClient(container);
        
        // 等待容器检查/创建完成
        await containerClient.CreateIfNotExistsAsync();
        Console.WriteLine("Existing blob obtained");

        string localPath = "./";
        string localFilePath = Path.Combine(localPath, fileName);
        
        // 先检查本地文件是否存在,避免无意义的上传
        if (!File.Exists(localFilePath)) {
            Console.WriteLine($"错误:本地文件 {localFilePath} 不存在!");
            return;
        }
        Console.WriteLine("Local file path set");

        BlobClient blobClient = containerClient.GetBlobClient(fileName);
        Console.WriteLine($"BlobClient established with filename {fileName}");

        // 使用using自动管理文件流,无需手动关闭
        using (var uploadFileStream = File.OpenRead(localFilePath)) {
            // 等待上传操作完成
            await blobClient.UploadAsync(uploadFileStream, true);
        }
        Console.WriteLine("Uploaded File to existing container");
    }

    public async Task CreateContainerAndUploadFileAsync(string containerName) {
        Console.WriteLine("Pre-container");
        // 复用类中已初始化的blobServiceClient
        BlobContainerClient containerClient = await blobServiceClient.CreateBlobContainerAsync(containerName + Guid.NewGuid());
        Console.WriteLine("Post-container");

        string localPath = "./";
        string fileName = "demo" + Guid.NewGuid().ToString() + ".txt";
        string localFilePath = Path.Combine(localPath, fileName);

        // 等待文件写入完成
        await File.WriteAllTextAsync(localFilePath, "Hello, World!");

        BlobClient blobClient = containerClient.GetBlobClient(fileName);
        Console.WriteLine($"Uploading to Blob storage as blob: {fileName}");

        using (var uploadFileStream = File.OpenRead(localFilePath)) {
            await blobClient.UploadAsync(uploadFileStream, true);
        }
    }
}

修改Main方法以支持异步调用

因为要调用异步方法,Main方法需要改成async Task类型:

public class Launcher {
    public static async Task Main(string[] args) {
        BlobManager manager = new BlobManager();
        await manager.UploadFileAsync("DemoText.txt", "democontainer");
        await manager.CreateContainerAndUploadFileAsync("demo");
    }
}

额外排查建议

  1. 验证连接字符串:确保StorageConnectionString配置的是正确的Azure存储账户连接字符串,没有拼写错误。
  2. 检查文件路径:确认DemoText.txt确实在程序运行的当前工作目录下(可以用Directory.GetCurrentDirectory()打印当前路径,验证文件位置)。
  3. 添加异常捕获:在异步方法中添加try-catch块,捕获上传过程中的异常,比如权限问题、网络问题等,方便定位问题:
try {
    await blobClient.UploadAsync(uploadFileStream, true);
} catch (Exception ex) {
    Console.WriteLine($"上传文件失败:{ex.Message}");
    throw;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 07:02:44