12

My code looks like this

CloudFileClient client = ...;

client.GetShareReference("fileStorageShare")
    .GetRootDirectoryReference()
    .GetDirectoryReference("one/two/three")
    .Create();

This errors if directories one or two don't exist. Is there a way to create these nested directories with a single call?

Ivan Glasenberg
  • 29,865
  • 2
  • 44
  • 60
sirdank
  • 3,351
  • 3
  • 25
  • 58
  • If I'm not mistaken, there is no nested directories in azure blob storage, it's a flat hierarchy only, you might be able to build a nested directory just so you can see it in the explorer and nothing more. – Ali_Nass Oct 01 '18 at 14:56
  • @bleh10 You're right for blob storage which is what file storage sits on top of but file storage does have some directory support. – sirdank Oct 01 '18 at 16:51
  • oh I never knew that! Thanks for the info, might get handy. Did you get any new result for your question? – Ali_Nass Oct 02 '18 at 06:53
  • 1
    @bleh10 Not yet. I suspect it will have to be a new feature. – sirdank Oct 02 '18 at 17:07

3 Answers3

18

It is impossible. The SDK does not support it this way, you should create them one by one.

A issue has already submitted here.

If you wanna create them one by one, you can use the following sample code:

static void NestedDirectoriesTest()
{
   var cred = new StorageCredentials(accountName, accountKey);
   var account = new CloudStorageAccount(cred, true);
   var client = account.CreateCloudFileClient();
   var share = client.GetShareReference("temp2");
   share.CreateIfNotExists();
   var cloudFileDirectory = share.GetRootDirectoryReference();

   //Specify the nested folder
   var nestedFolderStructure = "Folder/SubFolder";
   var delimiter = new char[] { '/' }; 
   var nestedFolderArray = nestedFolderStructure.Split(delimiter);
   for (var i=0; i<nestedFolderArray.Length; i++)
   {
       cloudFileDirectory = cloudFileDirectory.GetDirectoryReference(nestedFolderArray[i]);
       cloudFileDirectory.CreateIfNotExists();
       Console.WriteLine(cloudFileDirectory.Name + " created...");
   }
}
Ivan Glasenberg
  • 29,865
  • 2
  • 44
  • 60
6

Following the advice of Ivan Yang, I adapted my code using Azure.Storage.Files.Shares (Version=12.2.3.0).

Here's my contribution:

readonly string storageConnectionString = "yourConnectionString";
readonly string shareName = "yourShareName";

public string StoreFile(string dirName,string fileName, Stream fileContent)
{
    // Get a reference to a share and then create it
    ShareClient share = new ShareClient(storageConnectionString, shareName);
    share.CreateIfNotExists();

    // Get a reference to a directory and create it
    string[] arrayPath = dirName.Split('/');
    string buildPath = string.Empty;
    var tempoShare = share;
    ShareDirectoryClient directory = null; // share.GetDirectoryClient(dirName);
    // Here's goes the nested directories builder
    for (int i=0; i < arrayPath.Length; i++)
    {
        buildPath += arrayPath[i];
        directory = share.GetDirectoryClient(buildPath);
        directory.CreateIfNotExists();
        buildPath += '/';
    }
     // Get a reference to a file and upload it
    ShareFileClient file = directory.GetFileClient(fileName);
    using (Stream stream = fileContent)
    {
        file.Create(stream.Length);
        file.UploadRange(new HttpRange(0, stream.Length), stream);
    }
    return directory.Path;
}
Dharman
  • 30,962
  • 25
  • 85
  • 135
Hagen
  • 111
  • 3
  • 8
5

Here is a simplified version of Hagen's code:

public async Task<ShareFileClient> CreateFileClient(string connection, string shareName, string path)
{
    var share = new ShareClient(connection, shareName);
    await share.CreateIfNotExistsAsync();

    var dir = share.GetRootDirectoryClient();
    var pathChain = path.Split(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar);
    int dirCount = pathChain.Length - 1;

    for (int i = 0; i < dirCount; ++i)
    {
        dir = dir.GetSubdirectoryClient(pathChain[i]);
        await dir.CreateIfNotExistsAsync();
    }

    return dir.GetFileClient(pathChain[dirCount]);
}
Herman Kan
  • 2,253
  • 1
  • 25
  • 32