sourcetip

Azure Blob Storage에서 브라우저로 파일을 다운로드하는 방법

fileupload 2023. 4. 23. 11:03
반응형

Azure Blob Storage에서 브라우저로 파일을 다운로드하는 방법

이미 사용 가능한 파일을 정상적으로 나열하고 있습니다만, 그 파일을 서버에 저장하지 않고 사용자가 다운로드 할 수 있도록 브라우저에 전달할 수 있는 방법이 필요했습니다.

파일 목록을 가져오는 방법은 다음과 같습니다.

var azureConnectionString = CloudConfigurationManager.GetSetting("AzureBackupStorageConnectString");
var containerName = ConfigurationManager.AppSettings["FmAzureBackupStorageContainer"];
if (azureConnectionString == null || containerName == null)
    return null;

CloudStorageAccount backupStorageAccount = CloudStorageAccount.Parse(azureConnectionString);
var backupBlobClient = backupStorageAccount.CreateCloudBlobClient();
var container = backupBlobClient.GetContainerReference(containerName); 
var blobs = container.ListBlobs(useFlatBlobListing: true);
var downloads = blobs.Select(blob => blob.Uri.Segments.Last()).ToList();

BLOB 콘텐츠는 웹 서버 및 브라우저를 통해 최종 사용자에게 스트리밍할 수 있지만 이 솔루션은 웹 서버(CPU 및 NIC)에 부하를 줍니다.

또 하나의 방법은 최종 사용자에게 다운로드 대상 blob에 URI를 제공하는 것입니다.이 BLOB는 html 콘텐츠 내에서 클릭할 수 있습니다.https://myaccount.blob.core.windows.net/mycontainer/myblob.ext.

위의 uri와 같은 uri는 퍼블릭블럽을 사용하지 않으면 작동하지 않기 때문에 이 컨텐츠가 비공개인 경우 문제가 됩니다.이를 위해 공유 액세스시그니처(또는 서버에 저장된 정책)를 생성하여 해시 쿼리 스트링을 URI에 추가할 수 있습니다.이 새로운 uri는 소정의 시간(예를 들어 10분) 동안 유효합니다.

다음은 BLOB용 SAS를 작성하는 간단한 예입니다.

var sasConstraints = new SharedAccessBlobPolicy();
sasConstraints.SharedAccessStartTime = DateTime.UtcNow.AddMinutes(-5);
sasConstraints.SharedAccessExpiryTime = DateTime.UtcNow.AddMinutes(10);
sasConstraints.Permissions = SharedAccessBlobPermissions.Read;

var sasBlobToken = blob.GetSharedAccessSignature(sasConstraints);

return blob.Uri + sasBlobToken;

시작 시간은 과거 몇 분으로 설정되어 있습니다.이것은 클럭 드리프트에 대처하기 위한 것입니다.이 코드 샘플을 가져오거나 수정한 전체 튜토리얼입니다.

직접 BLOB 액세스를 사용하면 VM/웹 역할 인스턴스/웹 사이트 인스턴스를 완전히 바이패스하여(서버 부하를 줄여), 최종 사용자가 BLOB 스토리지에서 직접 BLOB 컨텐츠를 풀 수 있습니다.웹 앱을 사용하여 권한 부여, 전송할 콘텐츠 결정 등을 수행할 수 있습니다. 하지만...이를 통해 웹 서버를 통해 스트리밍하지 않고 BLOB 리소스에 직접 연결할 수 있습니다.

사용자가 파일을 클릭하면 서버는 다음과 같이 응답합니다.

var blob = container.GetBlobReferenceFromServer(option);

var memStream = new MemoryStream();
blob.DownloadToStream(memStream);

Response.ContentType = blob.Properties.ContentType;
Response.AddHeader("Content-Disposition", "Attachment;filename=" + option);
Response.AddHeader("Content-Length", blob.Properties.Length.ToString());
Response.BinaryWrite(memStream.ToArray());

솔루션에 대해 Dhanjay Kumar에게 큰 감사를 표합니다.

ASP를 사용하는 경우.NET(코어)에서는 서버에 파일을 저장하지 않고 콘텐츠를 브라우저로 스트리밍할 수 있습니다.FileStreamResult(IActionResult)를 사용하면 보다 우아한 솔루션이 됩니다.

var stream = await blob.OpenReadAsync();
return File(stream, blob.Properties.ContentType, option);

BLOB 파일을 업로드 및 다운로드 할 수 있는 샘플을 작성했습니다.

using System;
using System.Threading.Tasks;
using System.IO;
using Microsoft.Azure.Storage;
using Microsoft.Azure.Storage.Blob;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System.Linq;
using System.Collections.Generic;

namespace GetBackup
{
    class Program
    {
        static async Task Main(string[] args)
        {
            string Config_string = "";

            using (StreamReader SourceReader = File.OpenText(@"appsettings.json"))
            {
                Config_string = await SourceReader.ReadToEndAsync();
            }

            var config = (JObject)JsonConvert.DeserializeObject(Config_string);

            if(config["Application_type"].ToString()== "Backup")
            {
                string Dir_path = config["Backup_Path"].ToString();
                string[] allfiles = Directory.GetFiles(Dir_path, "*.*", SearchOption.AllDirectories);


                string storageConnectionString = config["AZURE_STORAGE_CONNECTION_STRING"].ToString();
                CloudStorageAccount storageAccount;
                if (CloudStorageAccount.TryParse(storageConnectionString, out storageAccount))
                {
                    CloudBlobClient cloudBlobClient = storageAccount.CreateCloudBlobClient();
                    CloudBlobContainer cloudBlobContainer = cloudBlobClient.GetContainerReference("rtddata");
                    //await cloudBlobContainer.CreateAsync();

                    string[] ExcludeFiles = config["Exception_File"].ToString().Split(',');

                    foreach (var file in allfiles)
                    {
                        FileInfo info = new FileInfo(file);
                        if (!ExcludeFiles.Contains(info.Name))
                        {
                            string folder = (Dir_path.Length < info.DirectoryName.Length) ? info.DirectoryName.Replace(Dir_path, "") : "";
                            folder = (folder.Length > 0) ? folder + "/" : "";
                            CloudBlockBlob cloudBlockBlob = cloudBlobContainer.GetBlockBlobReference(folder + info.Name);
                            await cloudBlockBlob.UploadFromFileAsync(info.FullName);
                        }

                    }

                }
            }
            
            else if (config["Application_type"].ToString() == "Restore")
            {
                string storageConnectionString = config["AZURE_STORAGE_CONNECTION_STRING"].ToString();
                CloudStorageAccount storageAccount;
               
                if (CloudStorageAccount.TryParse(storageConnectionString, out storageAccount))
                {
                    CloudBlobClient cloudBlobClient = storageAccount.CreateCloudBlobClient();
                    CloudBlobContainer cloudBlobContainer = cloudBlobClient.GetContainerReference("rtddata");
                    string Dir_path = config["Restore_Path"].ToString();

                    IEnumerable<IListBlobItem> results = cloudBlobContainer.ListBlobs(null,true);  
                    foreach (IListBlobItem item in results)
                    {
                        string name = ((CloudBlockBlob)item).Name;
                        if (name.Contains('/'))
                        {
                            string[] subfolder = name.Split('/');
                            if (!Directory.Exists(Dir_path + subfolder[0]))
                            {
                                Directory.CreateDirectory(Dir_path + subfolder[0]);
                            }
                            
                        }  
                            CloudBlockBlob blockBlob = cloudBlobContainer.GetBlockBlobReference(name);
                            string path = (Dir_path + name);
                            blockBlob.DownloadToFile(path, FileMode.Create);
                    }
                    

                }
                    
            }

            
            
        }
    }
}

언급URL : https://stackoverflow.com/questions/30467013/how-to-download-a-file-to-browser-from-azure-blob-storage

반응형