I am trying to download a dll from Azure blobl storage and read its version.
When I download it by hand all the properties are there but when I download it with my code there is nothing:
This is the code I am using:
Stream file = File.OpenWrite(Path.Combine(downloadPath,blobName));
BlobClient blobClient = new BlobClient(connectionString, containerName, blobName);
blobClient.DownloadTo(file);
I tried in my environment and successfully downloaded dll files from azure blob storage.
Code:
using Azure.Storage.Blobs;
namespace blobdll
{
class program
{
public static void Main()
{
var connectionString = < Connection string>;
var downloadPath = "< path of folder upto filename >";
using Stream file = File.OpenWrite(Path.Combine(downloadPath));
BlobClient blobClient = new BlobClient(connectionString, "test", "A2dLib-3.17.dll");
blobClient.DownloadTo(file);
}
}
}
Console:
Portal:
Downloaded file:
After downloaded file, I checked the size of the file it is in same size.
Related
I have a zip file(.Exe - Self-extracting zip file) that can be extracted using 7zip. As I want to automate the extraction process, I used the below C# code. It is working for the normal 7z files. But facing this issue 'Cannot access the closed Stream', when I trying to extract the specific self-extracting (.Exe) zip file. Fyi. Manually I ensured the 7zip command line version is unzipping the file.
using (SevenZipExtractor extract = new SevenZipExtractor(zipFileMemoryStream))
{
foreach (ArchiveFileInfo archiveFileInfo in extract.ArchiveFileData)
{
if (!archiveFileInfo.IsDirectory)
{
using (var memory = new MemoryStream())
{
string shortFileName = Path.GetFileName(archiveFileInfo.FileName);
extract.ExtractFile(archiveFileInfo.Index, memory);
byte[] content = memory.ToArray();
file = new MemoryStream(content);
}
}
}
}
The zip file is in Azure blob storage. I dont know how to get the extracted files in the blob storage.
Here is one of the workarounds that has worked for me. Instead of 7Zip I have used ZipArchive.
ZipArchive archive = new ZipArchive(myBlob);
CloudStorageAccount storageAccount = CloudStorageAccount.Parse(destinationStorage);
CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
CloudBlobContainer container = blobClient.GetContainerReference(destinationContainer);
foreach(ZipArchiveEntry entry in archive.Entries) {
log.LogInformation($"Now processing {entry.FullName}");
string valideName = Regex.Replace(entry.Name, # "[^a-zA-Z0-9\-]", "-").ToLower();
CloudBlockBlob blockBlob = container.GetBlockBlobReference(valideName);
using(var fileStream = entry.Open()) {
await blockBlob.UploadFromStreamAsync(fileStream);
}
}
REFERENCE:
How to Unzip Automatically your Files with Azure Function v2
I can read txt file with this code, but when I try to read the txt.gz file of course it doesn't work.
How can I read zipped blob without downloading, because the framework will work on cloud?
Maybe it is possible to unzip the file to another container? But I couldn't find a solution.
public static string GetBlob(string containerName, string fileName)
{
string connectionString = $"yourConnectionString";
// Setup the connection to the storage account
CloudStorageAccount storageAccount = CloudStorageAccount.Parse(connectionString);
// Connect to the blob storage
CloudBlobClient serviceClient = storageAccount.CreateCloudBlobClient();
// Connect to the blob container
CloudBlobContainer container = serviceClient.GetContainerReference($"{containerName}");
// Connect to the blob file
CloudBlockBlob blob = container.GetBlockBlobReference($"{fileName}");
// Get the blob file as text
string contents = blob.DownloadTextAsync().Result;
return contents;
}
You can use GZipStream to decompress your gz file on the fly, you don't have to worry about downloading it and decompressing it on a physical location.
public static string GetBlob(string containerName, string fileName)
{
string connectionString = $"connectionstring";
// Setup the connection to the storage account
CloudStorageAccount storageAccount = CloudStorageAccount.Parse(connectionString);
// Connect to the blob storage
CloudBlobClient serviceClient = storageAccount.CreateCloudBlobClient();
// Connect to the blob container
CloudBlobContainer container = serviceClient.GetContainerReference($"{containerName}");
// Connect to the blob file
CloudBlockBlob blob = container.GetBlockBlobReference($"{fileName}");
// Get the blob file as text
using (var gzStream = await blob.OpenReadAsync())
{
using (GZipStream decompressionStream = new GZipStream(gzStream, CompressionMode.Decompress))
{
using (StreamReader reader = new StreamReader(decompressionStream, Encoding.UTF8))
{
return reader.ReadToEnd();
}
}
}
}
without downloading, because the framework will work on cloud
This is not possible. You cannot work with a file on blob storage without downloading it. No matter where your code is running. Of course, if your code is also running on Azure, the download time might be pretty fast, but nevertheless you have to download from blob storage first.
And for your zip file you want to use either DownloadToFileAsync() or DownloadToStreamAsync().
I am trying to load a JSON string (serialized with Newtonsoft.Json) without creating a temporary file.
I am serializing object in runtime using JsonConvert.SerializeObject(obj,settings) which returns a string.
Following Microsoft documentation I could do as it's illustrated below:
// Create a local file in the ./data/ directory for uploading and downloading
string localPath = "./data/";
string fileName = "quickstart" + Guid.NewGuid().ToString() + ".txt";
string localFilePath = Path.Combine(localPath, fileName);
// Write text to the file
await File.WriteAllTextAsync(localFilePath, "Hello, World!");
// Get a reference to a blob
BlobClient blobClient = containerClient.GetBlobClient(fileName);
Console.WriteLine("Uploading to Blob storage as blob:\n\t {0}\n", blobClient.Uri);
// Open the file and upload its data
using FileStream uploadFileStream = File.OpenRead(localFilePath);
await blobClient.UploadAsync(uploadFileStream, true);
uploadFileStream.Close();
Although it works, I would have to create temporary file for each uploaded JSON file.
I tried this:
BlobServiceClient blobServiceClient = new BlobServiceClient("SECRET");
BlobContainerClient container = BlobServiceClient.GetBlobContainerClient("CONTAINER_NAME");
container.CreateIfNotExistsAsync().Wait();
container.SetAccessPolicy(Azure.Storage.Blobs.Models.PublicAccessType.Blob);
CloudBlockBlob cloudBlockBlob = new CloudBlockBlob(container.Uri);
var jsonToUplaod = JsonConvert.SerializeObject(persons, settings);
cloudBlockBlob.UploadTextAsync(jsonToUpload).Wait();
But, well...it doesn't have right to work as I am not specifing any actual file in the given container (I don't know where to do it).
Is there any way to upload a blob directly to a given container?
Thank You in advance.
The BlobClient class wants a Stream, so you can create a MemoryStream from your JSON string.
Try something like this:
BlobClient blob = container.GetBlobClient("YourBlobName");
using (MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(jsonToUpload)))
{
await blob.UploadAsync(ms);
}
I want to read files from an azure blob storage (the files inside the folder), the blob storage contains many folders.
I want to read my folder 'blobstorage' ,it contains many JSON files performing .read to each file and some manipulations. I tried many code that did not work:
CloudStorageAccount storageAccount = CloudStorageAccount.Parse(connectionString);
CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
CloudBlobContainer container = blobClient.GetContainerReference($"blobstorage");
The above code uses 'Microsoft.WindowsAzure.Storage' nuget package. This code is not working as expected.
In many questions and answers found in stack overflow I found that most of them are outdated and does not work.
Note: if any nuget mention that also bcs they are many packages
I found the solution in this post and worked perfectly for me. You just have to read it as a normal stream after the download.
BlobServiceClient blobServiceClient = new BlobServiceClient("connectionString");
BlobContainerClient containerClient = blobServiceClient.GetBlobContainerClient("containerName");
BlobClient blobClient = containerClient.GetBlobClient("blobName.csv");
if (await blobClient.ExistsAsync())
{
var response = await blobClient.DownloadAsync();
using (var streamReader= new StreamReader(response.Value.Content))
{
while (!streamReader.EndOfStream)
{
var line = await streamReader.ReadLineAsync();
Console.WriteLine(line);
}
}
}
I don't see any option to list all blob using Microsoft.WindowsAzure.Storage package. If you can use Azure.Storage.Blobs package then try below code.
using Azure.Storage.Blobs;
using Azure.Storage.Blobs.Models;
using System;
namespace ConsoleApp2
{
class Program
{
static string connectionString = "DefaultEndpointsProtocol=https;AccountName=storage******c9709;AccountKey=v**************************************;EndpointSuffix=core.windows.net";
static string container = "azure-webjobs-hosts";
static void Main(string[] args)
{
// Get a reference to a container named "sample-container" and then create it
BlobContainerClient blobContainerClient = new BlobContainerClient(connectionString, container);
blobContainerClient.CreateIfNotExists();
Console.WriteLine("Listing blobs...");
// List all blobs in the container
var blobs = blobContainerClient.GetBlobs();
foreach (BlobItem blobItem in blobs)
{
Console.WriteLine("\t" + blobItem.Name);
}
Console.Read();
}
}
}
Output
You can also download the content of blob, Check this link
If you have mass data to download and are looking for efficiency, you probably don't want to download them 1 by 1 on a single thread. Use multiple threads and async.
Here's a good read on the topic:
https://learn.microsoft.com/en-us/azure/storage/blobs/storage-blob-scalable-app-download-files?tabs=dotnet
downloading 1000 files:
with single-thread : 30seconds download time
with multi-thread : 4seconds download time
You can find example code in the SDK github repo here for c#:
https://github.com/Azure/azure-sdk-for-net/tree/Azure.Storage.Blobs_12.8.0/sdk/storage/Azure.Storage.Blobs/
You can use the following command to add the package to your dotNet Core project.
dotnet add package Azure.Storage.Blobs
Based on the examples there, you can enumerate the blobs and then read the one you're looking for.
Try Below Code Out :
var connectionString = "your connection string";
CloudStorageAccount storageacc = CloudStorageAccount.Parse(connectionString);
//Create Reference to Azure Blob
CloudBlobClient blobClient = storageacc.CreateCloudBlobClient();
CloudBlobContainer container = blobClient.GetContainerReference("containerName");
var blobs = container.GetDirectoryReference("FolderName").GetDirectoryReference("FolderName").ListBlobs().OfType<CloudBlockBlob>().ToList();
Console.WriteLine("Total files found in directory: " + blobs.Count.ToString());
var tempBlobList = blobs.Where(b => b.Name.Contains("fileName")).ToList();
var response = await tempBlobList[0].DownloadTextAsync();
I have tried to upload the files in to my azure blob using below code
public async void UploadSync(IEnumerable<IFormFile> files, string path)
{
string MyPath = path.Replace("https://browsercontent.blob.core.windows.net/blob1/", "");
try
{
foreach (var file in files)
{
var newBlob = container.GetBlockBlobReference(MyPath);
await newBlob.UploadFromFileAsync(#"C:\Users\joy\Downloads\" + file.FileName);
}
}
catch (Exception ex)
{ throw ex;}
}
Actually i have upload the jpg file but it upload in a "application/octact steam" type. how to resolve it?
And my scenario is while uploading the file, windows explorer will open to select the file to upload. So if we provide the path as static as below,
newBlob.UploadFromFileAsync(#"C:\Users\joy\Downloads\" + file.FileName);
it will not be applicable for application. How to change this code to upload the files from various locations?
Try to use UploadFromStream and let me know the outcome
// 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".
CloudBlockBlob blockBlob = container.GetBlockBlobReference("myblob");
// Create or overwrite the "myblob" blob with contents from a local file.
using (var fileStream = System.IO.File.OpenRead(#"path\myfile"))
{
blockBlob.UploadFromStream(fileStream);
}
https://learn.microsoft.com/en-us/azure/storage/blobs/storage-dotnet-how-to-use-blobs