如何在不将文件保存在本地存储上的情况下将对象传输到 Azure Blob 存储?

Posted

技术标签:

【中文标题】如何在不将文件保存在本地存储上的情况下将对象传输到 Azure Blob 存储?【英文标题】:How to transfer objects to Azure Blob Storage without saving file on local storage? 【发布时间】:2020-02-04 06:23:10 【问题描述】:

我一直关注此example from GitHub 将文件传输到 Azure Blob 存储。该程序在本地 MyDocuments 文件夹中创建一个文件以上传到 blob 容器。创建文件后,它会将其上传到容器中。是否可以在内存中创建 JSON 对象并将它们发送到 Azure Blob 存储,而无需先将该文件写入硬盘驱动器?

namespace storage_blobs_dotnet_quickstart

    using Microsoft.Azure.Storage;
    using Microsoft.Azure.Storage.Blob;
    using System;
    using System.IO;
    using System.Threading.Tasks;

    public static class Program
    
        public static void Main()
        
            Console.WriteLine("Azure Blob Storage - .NET quickstart sample");
            Console.WriteLine();
            ProcessAsync().GetAwaiter().GetResult();

            Console.WriteLine("Press any key to exit the sample application.");
            Console.ReadLine();
        

        private static async Task ProcessAsync()
        
            CloudStorageAccount storageAccount = null;
            CloudBlobContainer cloudBlobContainer = null;
            string sourceFile = null;
            string destinationFile = null;

            // Retrieve the connection string for use with the application. The storage connection string is stored
            // in an environment variable on the machine running the application called storageconnectionstring.
            // If the environment variable is created after the application is launched in a console or with Visual
            // Studio, the shell needs to be closed and reloaded to take the environment variable into account.
            string storageConnectionString = Environment.GetEnvironmentVariable("storageconnectionstring");

            // Check whether the connection string can be parsed.
            if (CloudStorageAccount.TryParse(storageConnectionString, out storageAccount))
            
                try
                
                    // Create the CloudBlobClient that represents the Blob storage endpoint for the storage account.
                    CloudBlobClient cloudBlobClient = storageAccount.CreateCloudBlobClient();

                    // Create a container called 'quickstartblobs' and append a GUID value to it to make the name unique. 
                    cloudBlobContainer = cloudBlobClient.GetContainerReference("quickstartblobs" + Guid.NewGuid().ToString());
                    await cloudBlobContainer.CreateAsync();
                    Console.WriteLine("Created container '0'", cloudBlobContainer.Name);
                    Console.WriteLine();

                    // Set the permissions so the blobs are public. 
                    BlobContainerPermissions permissions = new BlobContainerPermissions
                    
                        PublicAccess = BlobContainerPublicAccessType.Blob
                    ;
                    await cloudBlobContainer.SetPermissionsAsync(permissions);

                    // Create a file in your local MyDocuments folder to upload to a blob.
                    string localPath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
                    string localFileName = "QuickStart_" + Guid.NewGuid().ToString() + ".txt";
                    sourceFile = Path.Combine(localPath, localFileName);
                    // Write text to the file.
                    File.WriteAllText(sourceFile, "Hello, World!");

                    Console.WriteLine("Temp file = 0", sourceFile);
                    Console.WriteLine("Uploading to Blob storage as blob '0'", localFileName);
                    Console.WriteLine();

                    // Get a reference to the blob address, then upload the file to the blob.
                    // Use the value of localFileName for the blob name.
                    CloudBlockBlob cloudBlockBlob = cloudBlobContainer.GetBlockBlobReference(localFileName);
                    await cloudBlockBlob.UploadFromFileAsync(sourceFile);

                    // List the blobs in the container.
                    Console.WriteLine("Listing blobs in container.");
                    BlobContinuationToken blobContinuationToken = null;
                    do
                    
                        var resultSegment = await cloudBlobContainer.ListBlobsSegmentedAsync(null, blobContinuationToken);
                        // Get the value of the continuation token returned by the listing call.
                        blobContinuationToken = resultSegment.ContinuationToken;
                        foreach (IListBlobItem item in resultSegment.Results)
                        
                            Console.WriteLine(item.Uri);
                        
                     while (blobContinuationToken != null); // Loop while the continuation token is not null.
                    Console.WriteLine();

                    // Download the blob to a local file, using the reference created earlier. 
                    // Append the string "_DOWNLOADED" before the .txt extension so that you can see both files in MyDocuments.
                    destinationFile = sourceFile.Replace(".txt", "_DOWNLOADED.txt");
                    Console.WriteLine("Downloading blob to 0", destinationFile);
                    Console.WriteLine();
                    await cloudBlockBlob.DownloadToFileAsync(destinationFile, FileMode.Create);
                
                catch (StorageException ex)
                
                    Console.WriteLine("Error returned from the service: 0", ex.Message);
                
                finally
                
                    Console.WriteLine("Press any key to delete the sample files and example container.");
                    Console.ReadLine();
                    // Clean up resources. This includes the container and the two temp files.
                    Console.WriteLine("Deleting the container and any blobs it contains");
                    if (cloudBlobContainer != null)
                    
                        await cloudBlobContainer.DeleteIfExistsAsync();
                    
                    Console.WriteLine("Deleting the local source file and local downloaded files");
                    Console.WriteLine();
                    File.Delete(sourceFile);
                    File.Delete(destinationFile);
                
            
            else
            
                Console.WriteLine(
                    "A connection string has not been defined in the system environment variables. " +
                    "Add a environment variable named 'storageconnectionstring' with your storage " +
                    "connection string as a value.");
            
        
    

【问题讨论】:

docs.microsoft.com/en-us/dotnet/api/… 应该能帮到你 【参考方案1】:

还有一些其他内置方法可以上传到 blob 存储,而无需先存储在本地驱动器中。

对于您的情况,您可以考虑以下内置方法:

1.上传流(示例见here):

UploadFromStream / UploadFromStreamAsync

2.上传字符串/文本(示例见here):

UploadText / UploadTextAsync

【讨论】:

【参考方案2】:

是的,您可以使用流、字节数组、文本和文件进行上传。

UploadFromFileAsync UploadFromByteArrayAsync UploadFromStreamAsync UploadFromTextAsync

CloudBlockBlob Class

我建议您创建一个 Blob 存储库接口并使用此接口实现您的 Azure Blob 存储库类。

通过这种方式,如果您需要更改您的支持 blob 存储库,您将能够这样做,而对其余代码的影响最小。

【讨论】:

以上是关于如何在不将文件保存在本地存储上的情况下将对象传输到 Azure Blob 存储?的主要内容,如果未能解决你的问题,请参考以下文章

是否可以从一个字符串本地保存数据,然后在不将其移动到其他地方的情况下进行破坏?

如何在不将 csv 保存到磁盘的情况下将 csv 格式的数据从内存发送到数据库?

RESTkit,Core Data:在将对象传输到 Core Data 之前对其进行处理

如何在不将旧根保存在堆栈中的情况下切换到新根?

如何在不将数据保存到数据库的情况下更新 Gridview 行

Python 3:如何在不保存在磁盘上的情况下将 pandas 数据帧作为 csv 流上传?