programing

Azure Blob 스토리지입니다.DownloadToByteArray VS DownloadToStream입니다.

fastcode 2023. 4. 25. 23:12
반응형

Azure Blob 스토리지입니다.DownloadToByteArray VS DownloadToStream입니다.

Azure Blob Storage 서비스를 사용하여 Azure Web Pages에서 호스팅할 웹 페이지와 관련하여 파일을 저장/복구하고 있습니다.

학습 과정 중에 두 가지 해결책을 제시했습니다. 첫 번째 솔루션은 기본적으로 다음과 같습니다.DownloadToStream같은 기능을 하지만, 같은 기능을 합니다.FileStream이 경우 파일을 사용자에게 반환하기 전에 서버에 작성해야 합니다.

public static Stream GetFileContent(string fileName, HttpContextBase context)
{
      CloudBlobContainer container = GetBlobContainer();    
      CloudBlockBlob blockBlob = container.GetBlockBlobReference(fileName);                                       
      Stream fileStream = new FileStream(
          context.Server.MapPath("~/App_Data/files/" + fileName), FileMode.Create);   
      blockBlob.DownloadToStream(fileStream);
      fileStream.Close();    
      return File.OpenRead(context.Server.MapPath("~/App_Data/files/" + fileName));
}

public ActionResult Download(string fileName)
{
    byte[] fileContent = MyFileContext.GetFileContent(fileName);
    return File(fileContent, "application/zip", fileName);        
}

다른 한편으로 나는 그것을 사용하였습니다.DownloadToByteArray함수는 Blob 파일의 크기로 초기화된 바이트 배열에 Blob의 내용을 씁니다.

public static byte[] GetFileContent(string fileName)
{
    CloudBlobContainer container = GetBlobContainer();           
    CloudBlockBlob blockBlob = container.GetBlockBlobReference(fileName);
    blockBlob.FetchAttributes();
    long fileByteLength = blockBlob.Properties.Length;
    byte[] fileContent = new byte[fileByteLength];
    for (int i = 0; i < fileByteLength; i++)
    {
        fileContent[i] = 0x20;
    }
    blockBlob.DownloadToByteArray(fileContent,0);
    return fileContent;
}

public ActionResult Download(string fileName)
{   
   byte[] fileContent = MyFileContext.GetFileStream(fileName);
   return File(fileContent, "application/zip", fileName);
}

두 가지 옵션을 모두 살펴보면 첫 번째 옵션은 서버의 디스크에 파일을 생성해야 하는 반면, 두 번째 옵션은 BLOB의 데이터를 바이트 배열에 저장하여 메모리를 소비합니다.제 경우 최대 150MB의 파일 크기를 처리할 예정입니다.

상황(환경, 파일 크기 등)을 고려할 때 어떤 접근 방식이 최선이라고 생각하십니까?

서버를 통해 BLOB를 스트리밍하는 대신 BLOB 스토리지에서 직접 다운로드할 수 있습니다.제 답변은 여기 Steve의 답변에 기초하고 있습니다: MVC3에서 Azure Blob 파일을 다운로드합니다.스토리지에서 직접 BLOB를 다운로드하려면 다음을 활용해야 합니다.Shared Access Signature (SAS). 최근 Azure Storage는 다음을 지정할 수 있는 향상된 기능을 도입했습니다.Content-DispositionSAS의 헤더입니다.수정된 코드를 참조하십시오.

    public static string GetDownloadLink(string fileName)
    {
        CloudBlobContainer container = GetBlobContainer();
        CloudBlockBlob blockBlob = container.GetBlockBlobReference(fileName);
        //Create an ad-hoc Shared Access Policy with read permissions which will expire in 12 hours
        SharedAccessBlobPolicy policy = new SharedAccessBlobPolicy()
        {
            Permissions = SharedAccessBlobPermissions.Read,
            SharedAccessExpiryTime = DateTime.UtcNow.AddHours(12),
        };
        //Set content-disposition header for force download
        SharedAccessBlobHeaders headers = new SharedAccessBlobHeaders()
        {
            ContentDisposition = string.Format("attachment;filename=\"{0}\"", fileName),
        };
        var sasToken = blockBlob.GetSharedAccessSignature(policy, headers);
        return blockBlob.Uri.AbsoluteUri + sasToken;
    }

    public ActionResult Download(string fileName)
    {
        var sasUrl = GetDownloadLink(fileName);
        //Redirect to SAS URL ... file will now be downloaded directly from blob storage.
        Redirect(sasUrl);
    }

Stream의 장점은 큰 바이트[]를 축적한 다음 전체 작업을 수행하는 대신 다운로드되는 대로 하나하나 처리할 수 있다는 것입니다.파일에 쓴 다음 전체 파일을 메모리로 읽어들이기 때문에 Stream을 사용하는 것은 실제로 도움이 되지 않습니다.스트림 API의 좋은 용도는 다운로드 스트림을 요청 응답 스트림에 직접 파이프 연결(MVC3에서 Azure Blob 파일 다운로드)하는 것입니다.

DownloadToBytesArray(비동기식 또는 비동기식)를 사용하려는 경우 바이트 배열의 초기 크기를 가져오려면 먼저 BLOB 특성을 가져와야 합니다.

DownloadToStream을 사용하려는 경우에는 사용하지 않아도 됩니다.이는 BLOB 스토리지에 저장된 HTTP 호출 중 하나이며, 제가 잘못 알고 있지 않다면 FetchAttributes()는 HTTP HEAD 요청으로 실행되며 이는 일반 트랜잭션으로 간주됩니다(즉, 비용이 많이 듭니다).

언급URL : https://stackoverflow.com/questions/24312527/azure-blob-storage-downloadtobytearray-vs-downloadtostream 입니다.

반응형