【问题标题】:How do I append to a file in an Azure storage file share?如何追加到 Azure 存储文件共享中的文件?
【发布时间】:2016-09-15 05:26:24
【问题描述】:

我想将条目写入存储在 Azure 文件存储中的日志文件。我目前有这个:

var log = "My log entry";

var client = _storageAccount.CreateCloudFileClient();
var share = client.GetShareReference(Config.LogShare);
share.CreateIfNotExists();
var root = share.GetRootDirectoryReference();
var logfile = root.GetFileReference("log.txt");
if (!logfile.Exists()) logfile.Create(0);

// What goes here to append to the file...?

我可以看到很多关于如何使用 Blob 执行此操作的示例,或者如何上传整个文件,但我如何仅追加到现有文件?

我试过这个:

var buffer = Encoding.GetEncoding("UTF-8").GetBytes(log.ToCharArray());

using (var fileStream = logfile.OpenWrite(0)) {
    fileStream.Write(buffer, (int)logfile.Properties.Length, buffer.Length);
}

然后我得到这个错误:

The remote server returned an error: (416) The range specified is invalid for the current size of the resource..

【问题讨论】:

    标签: file append azure-storage


    【解决方案1】:

    Azure 文件存储 REST API 不支持追加到现有文件。为此,请将文件共享作为驱动器挂载到您的计算机上,并像简单的本地文件一样附加到文件中。

    实际上,我不认为您真的需要根据上面的代码附加功能。您可以在 CloudFile.OpenWrite() / CloudFile.Create() 中指定文件大小,或者尝试CloudFile.UploadFromStream() 而不是 CloudFile.OpenWrite()。

    【讨论】:

    • 其实你可以追加...看我的回答:)
    【解决方案2】:

    你可以用 blob 来做到这一点https://blogs.msdn.microsoft.com/windowsazurestorage/2015/04/13/introducing-azure-storage-append-blob/

    遗憾的是它也不适用于文件

    【讨论】:

    【解决方案3】:

    此错误也可能是由于多线程访问造成的。 我敢打赌,如果您在访问文件之前尝试锁定文件,您将不会遇到这个问题。 有很多方法可以更新文件。 由于您已经设法获得共享、根目录、文件夹和文件。这是我的代码的一部分,对我有用。

    if (!fileLock.IsWriteLockHeld) fileLock.EnterWriteLock();
    
    
            try
            {
                using (var stream = new MemoryStream(content, false))
                {
                    file.UploadFromStream(stream, null, options);
                }
            }
            catch (Exception ex)
            {
                File.AppendAllText(FileName, ex.ToString());
            }
            finally
            {
                if (fileLock.IsWriteLockHeld)
                    fileLock.ExitWriteLock();
            }
    

    fileLock 声明为:

      protected ReaderWriterLockSlim fileLock = new ReaderWriterLockSlim();
    

    话虽如此,我并不是说这是最好的方法。 我希望你记住两件事: 1-锁定可能被多个线程访问的资源(这在AZURE中很常见) 2- 熟悉 Azure 提供的异步方法。在适合的情况下使用它们。

    回到关于附加到现有文件的原始问题.. CloudFile 的所有方法都会覆盖现有文件。云文件不适合频繁写入,如果经常写入它们确实会影响性能,加上lock对性能的影响,它们会很可怕。

    云文件旨在一劳永逸地存储大量数据,如果您想添加另一个批量,您可以选择创建另一个文件。 将所有数据留给客户端,直到它们达到一定大小,然后创建一个算法来选择文件名并一次性上传。

    【讨论】:

      【解决方案4】:

      我自己设法解决了这个问题。您只需要将文件的大小增加您要写入的新字节数,然后将新数据写入文件末尾的新空白空间,如下所示:

      var client = _storageAccount.CreateCloudFileClient();
      var share = client.GetShareReference(Config.LogShare);
      share.CreateIfNotExists();
      var root = share.GetRootDirectoryReference();
      var logfile = root.GetFileReference("log.txt");
      if (!logfile.Exists()) logfile.Create(0);
      
      var buffer = Encoding.UTF8.GetBytes($"{log}\r\n");
      
      logfile.Resize(logfile.Properties.Length + buffer.Length);
      
      using (var fileStream = logfile.OpenWrite(null)) {
          fileStream.Seek(buffer.Length * -1, SeekOrigin.End);
          fileStream.Write(buffer, 0, buffer.Length);
      }
      

      【讨论】:

      • 是的,这有点像“追加”,但实际上是通过1.调整大小,2.将数据写入新区域来完成的。追加应该是一个原子操作,它直接追加数据并使文件大小更大。 :)
      • fileStream.Seek(buffer.Length * -1, SeekOrigin.End);此行产生错误。 “Azure.Storage.Files.Shares:不支持指定的方法。”
      猜你喜欢
      • 2021-03-09
      • 2022-11-11
      • 2018-08-09
      • 2020-02-13
      • 2017-01-08
      • 2020-10-22
      • 2020-09-19
      • 2017-04-11
      • 2018-10-16
      相关资源
      最近更新 更多