我想将条目写入存储在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..
答案 0 :(得分:1)
Azure文件存储REST API不支持附加到现有文件。要实现此目的,请将文件共享作为驱动器安装到您的计算机上,并像简单的本地文件一样附加到文件中。
实际上,我认为您不需要为上面的代码添加功能。您可以在CloudFile.OpenWrite()/ CloudFile.Create()中指定文件大小,或尝试CloudFile.UploadFromStream()而不是CloudFile.OpenWrite()。
答案 1 :(得分:0)
我设法自己解决这个问题。您只需要根据要写入的新字节数增加文件大小,然后将新数据写入文件末尾的新空白区域,如下所示:
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);
}
答案 2 :(得分:0)
此错误也可能是由于多线程访问。 我敢打赌,如果您在访问文件之前尝试锁定文件,则不会遇到此问题。 有许多方法可以更新文件。 因为你已经设法获得共享,根,文件夹和文件..这是我的代码的一部分,对我有用。
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
对性能的影响,它们确实会影响性能,它们会非常糟糕。
云文件旨在一劳永逸地存储大量数据,如果您想添加另一个批量,您可以选择创建另一个文件。 将所有数据与客户端一起保存,直到达到一定的大小,并创建一个算法来选择文件名并一次上传所有文件。
答案 3 :(得分:0)
羞耻它也不能用于文件