2017-05-08 67 views
0

我使用c#將文件上傳到Azure Blob。 現在我想用ExcelDataReader讀取上傳的文件。Excel文件託管在Azure Blob上,如何將其讀入FileStream?

我正在使用下面的代碼。 其中_imageRootPathNos是文件被保存

FileStream stream = System.IO.File.Open(_imageRootPathNos + "/" + "ImEx.xlsx", FileMode.Open, FileAccess.Read); 

路徑(http://imor.blob.core.windows.net/files)我得到一個錯誤System.ArgumentException: 'URI格式不被支持。'

我缺少什麼?

回答

0

使用Azure存儲服務時,建議您使用Azure .NET SDK。該SDK公開了適當的方法來下載,上傳和管理你的容器和blob存儲。在這種情況下,你的代碼應該是這樣的:

// Retrieve storage account from connection string. 
CloudStorageAccount storageAccount = CloudStorageAccount.Parse(
    CloudConfigurationManager.GetSetting("StorageConnectionString")); 

// Create the blob client. 
CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient(); 

// Retrieve reference to a previously created container. 
CloudBlobContainer container = blobClient.GetContainerReference("files"); 

// Retrieve reference to a blob named "imex.xlsx". 
CloudBlockBlob blockBlob = container.GetBlockBlobReference("Imex.xlsx"); 

// Save blob contents to a file. 
using (var fileStream = System.IO.File.OpenWrite(@"path\myfile")) 
{ 
    blockBlob.DownloadToStream(fileStream); 
} 

你可以找到你需要關於如何使用此SDK中的所有信息:https://docs.microsoft.com/en-us/azure/storage/storage-dotnet-how-to-use-blobs

+1

我建議「想要」而不是「需要」,你可以直接使用JSON和web api。我建議使用SDK,因爲它可以幫助保護代碼免受Azure存儲API中的更改 – Mick

+1

OP正試圖使用​​ExcelDataReader,它可以從任何流(包括由HttpClient返回的流)讀取數據。下載對於網站,網絡應用程序或無服務器應用程序來說不是一個好主意,由於權限或可伸縮性的原因,寫入臨時文件夾不切實際 –

+0

在我的辯護中,雖然我可能很迂腐,但他沒有提到他試圖在網絡應用上實現這一點。不過,我同意使用您提出的解決方案可能更適合。 – Chris

0

我用這個代碼塊讀取Excel文件(上傳到Azure上)到數據集

Uri blobUri = new Uri(_imageRootPath + "/" + fileName); 
       var wc = new WebClient(); 
       var sourceStream = wc.DownloadData(blobUri); 
       Stream memoryStream = new MemoryStream(sourceStream); 
       IExcelDataReader excelReader = ExcelReaderFactory.CreateOpenXmlReader(memoryStream); 
       DataSet dsResult = excelReader.AsDataSet(); 
       return dsResult; 
+0

你已經有一個流,爲什麼*將數據複製到另一個,而不是直接從它讀取? –

+0

ExcelReaderFactory需要一個MemoryStream。 – sham

+0

那麼它不適用於FileStream。它需要一個*流*,而不是一個特定類型的流 –

2

不能使用標準FileSteam Azure的Blob存儲文件。正如克里斯的回答中所建議的,您可以使用Azure SDK來訪問該文件。或者,您可以使用Azure Blob Service API

另一種解決方案是使用Azure File Storage並創建映射網絡驅動器到文件存儲。然後,您可以使用您的代碼訪問該文件,就好像它位於本地或網絡存儲系統上一樣。

這兩種服務之間有許多技術上的區別。 隨着定價的提高,Azure文件存儲比Azure Blob存儲更昂貴,但是根據預期用途,兩者都相當便宜。

3

ExcelDataReader可以從任何流中讀取數據,而不僅僅是FileStream。您可以使用WebClient(過時),HttpClient或Azure SDK打開流並讀取blob。

讀取或下載blob會打開並讀取流。而不是例如。下載blob或將其所有內容讀取到緩衝區中,則直接訪問該流。無論您使用哪種技術,最終都會在單個網址上打開流以供閱讀。

就你而言,你可以下載並保持文件重用它,或者你可以直接從流中讀取。如果您沒有寫入磁盤文件的權限,或者如果您同時處理多個請求並且不想處理臨時文件存儲,您可能希望在Web應用程序中執行此操作。

使用HttpClient的,你可以使用GetStreamAsync方法來打開一個流:

var client=new HttpClient(); 
client.BaseAddress = new Uri("https://imor.blob.core.windows.net/files"); 
// Set headers and credentials 
// ... 
using(var stream=await client.GetStreamAsync("ImEx.xlsx")) 
{ 
    var excelReader = ExcelReaderFactory.CreateOpenXmlReader(stream); 
    //Process the data 
} 

隨着Azure的SDK,您可以使用CloudBlob.OpenRead方法:

var blob = container.GetBlockBlobReference("Imex.xlsx"); 
using(var stream=await blob.OpenReadAsync()) 
{ 
    var excelReader = ExcelReaderFactory.CreateOpenXmlReader(stream); 
    //Process the data 
} 

你可能想存儲數據存儲在內存緩衝區或文件中,例如用於緩存或重新處理。爲此,您可以分別創建一個MemoryStream或FileStream,並將數據從blob流複製到目標流。

隨着HttpClient的,您可以填寫一個內存緩衝區:

//To avoid reallocations, create a buffer large enough to hold the file 

using(var memStream=new MemoryStream(65536)) 
{ 
    using(var stream=await client.GetStreamAsync("ImEx.xlsx")) 
    { 
     await stream.CopyToAsync(memStream); 
    } 
    memStream.Position=0; 
    var excelReader = ExcelReaderFactory.CreateOpenXmlReader(memStream); 
} 

隨着SDK:

using(var memStream=new MemoryStream(65536)) 
{ 
    //..... 
    var blob = container.GetBlockBlobReference("Imex.xlsx"); 
    await stream.DownloadToStreamAsync(memStream); 
    memStream.Position=0; 
    var excelReader = ExcelReaderFactory.CreateOpenXmlReader(memStream); 
    //... 
} 

要下載一個文件,你可以用一個FileStream替換的MemoryStream。

+0

偉大的答案@Panagiotis。比我的完整得多 – Chris

+0

如果其中一個答案爲您提供瞭解決方案,您應該將其標記爲答案 – Mick

相關問題