I am trying to download a block blob from Azure storage explorer. I am able to download all the block blobs that exist in the root directory of my container. I am unable to download blobs that are nested in subfolders inside the container.
CloudBlockBlob blob = container.GetBlockBlobReference(fileName);
SharedAccessBlobPolicy sasConstraints = new SharedAccessBlobPolicy();
sasConstraints.SharedAccessExpiryTime = DateTimeOffset.UtcNow.AddHours(1);
sasConstraints.Permissions = SharedAccessBlobPermissions.Read;
string sasBlobToken = blob.GetSharedAccessSignature(sasConstraints);
return blob.Uri.AbsoluteUri + sasBlobToken;
I couldn't get the absolute path of blockBlob using GetBlockBlobReference(fileName). The below code solved my issue. I got the listing and then used LINQ to get the blockBlob with the absolute path details.
This post helped as well
do
{
var listingResult = await blobDirectory.ListBlobsSegmentedAsync(useFlatBlobListing, blobListingDetails, maxBlobsPerRequest, continuationToken, null, null);
//The below lined fetched the blockBlob with the correct directory details.
var blockBlob = listingResult.Results.Where(x => x.Uri.AbsolutePath.Contains(fileName)).Count()>0 ? (CloudBlockBlob)listingResult.Results.Where(x=>x.Uri.AbsolutePath.Contains(fileName)).FirstOrDefault():null;
if (blockBlob != null)
{
sasConstraints.SharedAccessExpiryTime = expiryTimeSAS;
sasConstraints.Permissions = SharedAccessBlobPermissions.Read;
string sasBlobToken = blockBlob.GetSharedAccessSignature(sasConstraints);
return blockBlob.Uri.AbsoluteUri + sasBlobToken;
}
continuationToken = listingResult.ContinuationToken;
} while (continuationToken != null);
Correct me if there is any other efficient way of pulling the blob information from a list of directories in a container.
Below Solution helps to access single File Absolute path residing under Directory( or Folder Path).
public static String GetBlobUri(string dirPath, string fileName)
{
//Get a reference to a blob within the container.
CloudStorageAccount storageAccount = CloudStorageAccount.Parse("Blob Key");
CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
CloudBlobContainer container = blobClient.GetContainerReference("Blob Container");
CloudBlockBlob blockBlob = container.GetBlockBlobReference(dirPath+fileName);
return blockBlob.Uri.AbsoluteUri;
}
Hope this helps someone trying to access Blob File path based on multi level Directory(Level1/Level2/Level3) path.
Just use the ListBlobs mentioned in the answer from Gaurav Mantri to retrieve all files (blobs) within your desired subfolder. Then iterate over it and download it:
var storageAccount = CloudStorageAccount.Parse("yourConnectionString");
var client = storageAccount.CreateCloudBlobClient();
var container = client.GetContainerReference("yourContainer");
var blobs = container.ListBlobs(prefix: "subdirectory1/subdirectory2", useFlatBlobListing: true);
foreach (var blob in blobs)
{
blob.DownloadToFileAsync("yourFilePath");
}
Related
This works exactly as it should. It uses the entire file path to save the blobs in Azure. However, I would like only the file names to be saved directly into the "container" (not the entire hierarchical structure). Is there a good way to do this?
string[] returnedPaths = Open_File_Dialog();
CloudStorageAccount storageAccount = CloudStorageAccount.Parse(CloudConfigurationManager.GetSetting("StorageConnectionString"));
// Create the blob client.
CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
// container
CloudBlobContainer container = blobClient.GetContainerReference(_jobID);
container.CreateIfNotExists();
foreach (var filePath in returnedPaths)
{
CloudBlockBlob blob = container.GetBlockBlobReference(filePath);
blob.UploadFromFile(filePath);
}
This was all that was needed.
foreach (var filePath in returnedPaths)
{
string fileName = Path.GetFileName(filePath);
CloudBlockBlob blob = container.GetBlockBlobReference(fileName);
blob.UploadFromFile(filePath);
}
I upgraded WindowsAzure.Storage to 4.0.3
I want to output to a webpage a list of blobs in a folder, where clicking on the link downloads the blob. As the blobs are in a secure container each URI needs a shared access signature.
I used to have:
var dir = Container.GetDirectoryReference(folderName);
List<IListBlobItem> blobs = dir.ListBlobs().ToList();
var blobsInFolder = new List<Uri>();
foreach (IListBlobItem listBlobItem in blobs)
{
var blob = Container.GetBlockBlobReference(listBlobItem.Uri.ToString());
string sasBlobToken = blob.GetSharedAccessSignature(_sasConstraints);
blobsInFolder.Add(new Uri(blob.Uri + sasBlobToken));
}
return blobsInFolder;
This no longer works as GetBlockBlobReference no longer accepts a URI but a filename. IListBlobItem does not include the filename.
I could start chopping up the Uri to get the folder and filename
var blob = Container.GetBlockBlobReference(folderName + "/" + Path.GetFileName(listBlobItem.Uri.AbsolutePath));
...but I feel that's going the wrong way (that I shouldn't have to do this?). Can someone point me in the right way please?
Try casting IListBlobItem to CloudBlockBlob
foreach (IListBlobItem listBlobItem in blobs)
{
var blob = (CloudBlockBlob) listBlobItem;
string sasBlobToken = blob.GetSharedAccessSignature(_sasConstraints);
blobsInFolder.Add(new Uri(blob.Uri + sasBlobToken));
}
return blobsInFolder;
I know Azure doesn't have actual subpaths, but if I have for example container/projectID/iterationNumber/filename.jpg and I delete a project, how can I delete from ProjectID? Is it possible through coding?
I don't want to use the azure application as I am creating a web app.
Thanks in Advance
EDIT:
This is the code provided by Microsoft to target on specific item:
// 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("mycontainer");
// Retrieve reference to a blob named "myblob.txt".
CloudBlockBlob blockBlob = container.GetBlockBlobReference("myblob.txt");
// Delete the blob.
blockBlob.Delete();
SystemDesignModel
public static SystemDesign returnImageURL(IListBlobItem item)
{
if (item is CloudBlockBlob)
{
var blob = (CloudBlockBlob)item;
return new SystemDesign
{
URL = blob.Uri.ToString(),
};
}
return null;
}
}
As you know, blob storage does not have the concept of subfolders. It has just 2 level hierarchy - container & blobs. So in essence, a subfolder is just a prefix that you attach to blob name. In your example, the actual file you uploaded is filename.jpg but its name from blob storage perspective is projectID/iterationNumber/filename.jpg.
Since there is no concept of subfolder, you just can't delete it like we do on our local computer. However there's a way. Blob storage provides a way to search for blobs starting with a certain blob prefix. So what you have to do is first list all blobs that start with certain prefix (projectID in your case) and then delete the blobs one at a time returned as a result of listing operations.
Take a look at sample code below:
CloudStorageAccount storageAccount = CloudStorageAccount.Parse(
CloudConfigurationManager.GetSetting("StorageConnectionString"));
var container = storageAccount.CreateCloudBlobClient().GetContainerReference("container");
BlobContinuationToken token = null;
do
{
var listingResult = container.ListBlobsSegmented("blob-prefix (projectID in your case)", true, BlobListingDetails.None, 5000, token, null, null);
token = listingResult.ContinuationToken;
var blobs = listingResult.Results;
foreach (var blob in blobs)
{
(blob as ICloudBlob).DeleteIfExists();
Console.WriteLine(blob.Uri.AbsoluteUri + " deleted.");
}
}
while (token != null);
I have created container on azure storage and with code below made it work to upload my files(blobs) in container. Now it says upload was successful however I can't figure out how to reach those files to download it. There is no documentation on the internet about it.
Any help would be appreciated to solve it.
// create Azure Storage
CloudStorageAccount storageAccount = CloudStorageAccount.Parse("DefaultEndpointsProtocol=https;AccountName=bireddy;AccountKey=8OMbjBeJR+SIYaSt0YtBUzivLKPX5ZbsGJeEY9vsX0BPbX3uy9KxOckK7LuLeH3ZbOh+NoEaiEIV/NWvZbFOrA==");
// create a blob client.
CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
// create a container
CloudBlobContainer container = blobClient.GetContainerReference("mycontainer");
// make it public
container.SetPermissions(
new BlobContainerPermissions {
PublicAccess = BlobContainerPublicAccessType.Container
});
// create a block blob
CloudBlockBlob blockBlob = container.GetBlockBlobReference(FileUpload1.FileName);
// upload to Azure Storage
// this has to be changed sometime later
blockBlob.Properties.ContentType = FileUpload1.PostedFile.ContentType;
blockBlob.UploadFromStream(FileUpload1.FileContent);
Grateful to your discussion.
There are a number of options to download your blobs:
Using PowerShell: See the Azure Storage Powershell guide here:
http://azure.microsoft.com/en-us/documentation/articles/storage-powershell-guide-full/
Using Command Line: See the documentation for the AzCopy tool here:
http://aka.ms/azcopy
Using your C# code: There is a guide here, that includes a section on how to download blobs:
http://azure.microsoft.com/en-us/documentation/articles/storage-dotnet-how-to-use-blobs/
Using GUI-based explorers: There are a number of third-party explorers, some of them are listed here:
http://blogs.msdn.com/b/windowsazurestorage/archive/2014/03/11/windows-azure-storage-explorers-2014.aspx
// Parse the connection string and return a reference to the storage account.
CloudStorageAccount storageAccount = CloudStorageAccount.Parse(CloudConfigurationManager.GetSetting("StorageConnectionString"));
//Create the Blob service client
CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
// Retrieve a reference to a container.
CloudBlobContainer container = blobClient.GetContainerReference("mycontainer");
// Retrieve reference to a blob named
CloudBlockBlob blockBlob2 = container.GetBlockBlobReference(document);
//using (var np = File.Open(#"C:\mydocuments\"+ document, FileMode.Create))
// blockBlob2.DownloadToStream(np, null, options, null);
byte[] fileBytes;
using (var fileStream = new MemoryStream())
{
blockBlob2.DownloadToStream(fileStream, null, options, null);
fileBytes = fileStream.ToArray();
}
return fileBytes;
I have a file at a remote url such as http://www.site.com/docs/doc1.xls and i would like to copy that file onto my BLOB storage account.
I am aware and know of uploading files to a BLOB storage but wasn't sure how this can be done for a file from remote URL.
Try looking at CloudBlockBlob.StartCopyFromBlob that takes a URI if you are using the .NET client library.
string accountName = "accountname";
string accountKey = "key";
string newFileName = "newfile2.png";
string destinationContainer = "destinationcontainer";
string sourceUrl = "http://www.site.com/docs/doc1.xls";
CloudStorageAccount csa = new CloudStorageAccount(new StorageCredentials(accountName, accountKey), true);
CloudBlobClient blobClient = csa.CreateCloudBlobClient();
var blobContainer = blobClient.GetContainerReference(destinationContainer);
blobContainer.CreateIfNotExists();
var newBlockBlob = blobContainer.GetBlockBlobReference(newFileName);
newBlockBlob.StartCopyFromBlob(new Uri(sourceUrl), null, null, null);
Gaurav posted about this when it first came out. Handy, and his post shows how to watch for completion since the operation is Async.