为何无法将本地现有文件上传至已有的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"); } }
额外排查建议
- 验证连接字符串:确保
StorageConnectionString配置的是正确的Azure存储账户连接字符串,没有拼写错误。 - 检查文件路径:确认
DemoText.txt确实在程序运行的当前工作目录下(可以用Directory.GetCurrentDirectory()打印当前路径,验证文件位置)。 - 添加异常捕获:在异步方法中添加
try-catch块,捕获上传过程中的异常,比如权限问题、网络问题等,方便定位问题:
try { await blobClient.UploadAsync(uploadFileStream, true); } catch (Exception ex) { Console.WriteLine($"上传文件失败:{ex.Message}"); throw; }
内容的提问来源于stack exchange,提问作者TheHapticCoder
相关产品推荐
相关产品推荐

