Bart
Bart

Reputation: 11

How to unzip file in Azure File Share using Azure Function?

I have an Azure Storage Account with Azure File share. I want to extract zip archive file to another dir in file share using Azure functions. I wrote this code in C#:

    CloudFileDirectory rootDirectory = cloudFileShare.GetRootDirectoryReference();
    CloudFileDirectory output = rootDirectory.GetDirectoryReference("output");
    CloudFile cloudFile = input.GetFileReference("archive1.zip");
    
    using (var stream = await cloudFile.OpenReadAsync())
    {

       var file1 = new ZipArchive(stream);

       foreach (var zipEntry in file1.Entries)
       {

          var file2 = output.GetFileReference(zipEntry.Name);

          var fileStream = zipEntry.Open();

          await file2.UploadFromStreamAsync(fileStream); //error is in this line

        }

   }

But I got the error:

System.Private.CoreLib: Exception while executing function: HttpTriggerExtract. Microsoft.WindowsAzure.Storage: 
Operation is not valid due to the current state of the object.

How to fix this?

Edit: I fix the error using MemoryStream in addition, this code works:

        foreach (var zipEntry in file1.Entries) {

            var fsz = output.GetFileReference(zipEntry.Name);

            using (var ms = new MemoryStream())
            {

                using (var fileStream = zipEntry.Open())
                {
                    await fileStream.CopyToAsync(ms);

                    ms.Seek(0, SeekOrigin.Begin);
                    await fsz.UploadFromStreamAsync(ms);

                }

            }

Upvotes: 0

Views: 1526

Answers (2)

The above answer helped me for my problem. With the new Azure Library (12.7.0) you have to code this way:

        string srcDir = @"sourcePath";
        string destDir = @"sourcePath\testStorageUnzip";
        string srcFileName = "AzureStorageZip.zip";

        string azureConnectionString = ConfigurationManager.AppSettings["beecloudfileshare_AzureStorageConnectionString"];

        StorageSharedKeyCredential credential = BeeFileManager.GetAzureStorageKeyCredential(azureConnectionString);
        Uri srcUri = new Uri("https:" + Path.Combine(srcDir, srcFileName).Replace("\\", "/"), UriKind.Absolute);
        Uri destDirUri = new Uri("https:" + Path.Combine(destDir).Replace("\\", "/"), UriKind.Absolute);
        // Get a reference to the file we created previously
        ShareFileClient sourceFile = new ShareFileClient(srcUri, credential);

        ShareDirectoryClient shareDirectoryClient = new ShareDirectoryClient(destDirUri,credential);
        shareDirectoryClient.CreateIfNotExistsAsync().GetAwaiter().GetResult();

        using (var stream = sourceFile.OpenRead())
        using (var zipArchive = new ZipArchive(stream))
        {
            foreach (var entry in zipArchive.Entries)
            {
                if (entry.Length > 0)
                {
                    //CloudFile extractedFile = output.GetFileReference(entry.Name);
                    Uri destUri = new Uri("https:" + Path.Combine(destDir, entry.Name).Replace("\\", "/"), UriKind.Absolute);
                    ShareFileClient extractedFile = new ShareFileClient(destUri, credential);

                    
                    using (var entryStream = entry.Open())
                    {
                        using (MemoryStream ms = new MemoryStream())
                        {
                            entryStream.CopyTo(ms);
                            //
                            //Sorry I have this part in another method
                            //
                            Uri fileUri = new Uri("https:" + Path.GetDirectoryName(filePath).Replace("\\", "/"), UriKind.Absolute);
                            // Get a reference to the file we created previously
                            ShareDirectoryClient directory = new ShareDirectoryClient(fileUri, credential);
                            ShareFileClient file = directory.GetFileClient(Path.GetFileName(filePath));
                            ms.Seek(0, SeekOrigin.Begin);
                            file.Create(ms.Length);
                            file.Upload(ms);
                            //
                            //
                            //
                        }
                    }
                }

            }

        }
    }

Upvotes: 0

Jim Xu
Jim Xu

Reputation: 23111

Regarding the issue, please refer to the following code (I use package WindowsAzure.Storage 9.3.1 to do that)

            CloudStorageAccount storageAccount = CloudStorageAccount.Parse(connectionString);
            CloudFileClient cloudFileClient = storageAccount.CreateCloudFileClient();
            CloudFileShare cloudFileShare = cloudFileClient.GetShareReference("share2");
            CloudFileDirectory rootDirectory = cloudFileShare.GetRootDirectoryReference();
            CloudFileDirectory input = rootDirectory.GetDirectoryReference("input");
            CloudFileDirectory output = rootDirectory.GetDirectoryReference("output");
            CloudFile cloudFile = input.GetFileReference("sample.zip");
            using (var stream = await cloudFile.OpenReadAsync())
            using (var zipArchive = new ZipArchive(stream)) {
                foreach (var entry in zipArchive.Entries)
                {
                    if (entry.Length > 0) {
                        CloudFile extractedFile = output.GetFileReference(entry.Name);

                        using (var entryStream = entry.Open())
                        {
                            byte[] buffer = new byte[16 * 1024];
                            using (var ms = await extractedFile.OpenWriteAsync(entry.Length))
                            {
                                int read;
                                while ((read = await entryStream.ReadAsync(buffer, 0, buffer.Length)) > 0)
                                {
                                    ms.Write(buffer, 0, read);
                                }
                            }
                        }
                    }
                
                }

            }

enter image description here

Upvotes: 1

Related Questions