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);
}
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 have to download some txt files which are in a Azure container allowing anonymous access. I am working with Visual Studio 2017 and the program is a Windows Form application.
This is my code (where myUri is the string containing the Uri and myContainer the one for the Container):
BlobServiceClient blobServiceClient = new BlobServiceClient(new Uri(myUri));
BlobContainerClient container = blobServiceClient.GetBlobContainerClient(myContainer);
Azure.Pageable<BlobItem> blobs = container.GetBlobs(BlobTraits.All,BlobStates.All);
foreach (BlobItem blob in blobs)
{
BlobClient bc = container.GetBlobClient(blob.Name);
bc.DownloadTo(new FileStream(path + blob.Name, FileMode.Create));
}
I can see the files in my local path with the correct names, the problem is that if I try to open the .txt(s) with a common editor such as Notepad++ I see encoded chars instead of normal ASCII.
Where is the problem? Can anyone help me?
(too long for comment)
While I am not able to see any issue in your code that would cause encoding issue, you may try the below to download your blob. Here I am using BlobDownloadInfo class to get an idea of the content type of what is being downloaded and it's Content.CopyTo method to write to the stream.
Azure.Pageable<BlobItem> blobs = container.GetBlobs(BlobTraits.All, BlobStates.All);
foreach (BlobItem blob in blobs)
{
BlobClient blobClient = container.GetBlobClient(blob.Name);
BlobDownloadInfo download = blobClient.Download();
Console.WriteLine("Content Type " + download.ContentType);
using (FileStream downloadFileStream = File.OpenWrite(Path.Combine(#"YourPath", blob.Name)))
{
download.Content.CopyTo(downloadFileStream);
downloadFileStream.Close();
}
}
I have a file named as MyFile_1.ext.
I want to upload the file to Azure blob, but with file name MyFile_2.ext
Is there any way to do that in c#?
Have a look at the example from the Microsoft Docs (Upload blobs to a container):
// 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);
uploadFileStream.Close();
The GetBlobClient method takes the desired blob file name as a parameter. So all you have to do is to pass it here...
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