如何解决Flush 和 Write 调用的特定组合会破坏通过 OpenWrite 使用的 BlockBlob 完整代码
我最近遇到了一个错误,或者至少是通过 .NET
客户端使用的 BlockBlobs 的一个非常奇怪的行为。
基本上,写入和刷新的特定组合会以某种方式损坏文件,如果您在写入后读回它,则响应流包含垃圾(更准确地说,它是一个截断和 最后写入的字节重复)。
复制(100% 几率):
- 组装 Azure.Storage.Blobs,版本=12.8.1.0,文化=中性,PublicKeyToken=92742159e12e44c8
- 使用 BlockBlobClient
- 使用 OpenWrite 获取可写流
- 写入 4 个字节(一次全部写入或一个一个写入)
- 在流上调用 Flush
- 再写入 2 个字节(一次全部写入或一个一个写入)
- 处理流
- 再读一遍为什么 OpenRead
- 看到书面和阅读版本是不同的
腐败示例:
var iterations = new List<byte[]?>()
{
new byte[] { 0x00 },new byte[] { 0x00 },null,new byte[] { 0xFF },new byte[] { 0xAA },};
written: 00000000FFAA
read: FFAAFFAA
成功示例:
var iterations = new List<byte[]?>()
{
new byte[] { 0x00 },};
written: 00000000FFAA
read: 00000000FFAA
这里最奇怪的是,如果您在损坏后再写入 1 个字节,那么损坏就会消失。只有当您的 blob 文件以 write4+flush+write2
序列结尾时才会发生这种情况。
有人看到过这样的东西吗?
完整代码
var containerClient = new BlobContainerClient(connectionSting,"test");
var blockBlobClient = containerClient.GetBlockBlobClient($"test{Guid.NewGuid():N}.data");
var iterations = new List<byte[]?>()
{
new byte[] { 0x00 },};
var writeStream = blockBlobClient.OpenWrite(true,new Azure.Storage.Blobs.Models.BlockBlobOpenWriteOptions()
{
HttpHeaders = new Azure.Storage.Blobs.Models.BlobHttpHeaders()
{
ContentType = "application/octet-stream"
}
});
var writeMemStream = new MemoryStream();
for (var i = 0; i < iterations.Count; i++)
{
var buffer = iterations[i];
if (buffer is null)
{
writeStream.Flush();
writeMemStream.Flush();
}
else
{
writeStream.Write(buffer,buffer.Length);
writeMemStream.Write(buffer,buffer.Length);
}
}
writeStream.dispose();
var readMemStream = new MemoryStream();
var readStream = blockBlobClient.OpenRead(options: new Azure.Storage.Blobs.Models.BlobOpenReadOptions(false)
{
Position = 0
});
readStream.copyTo(readMemStream);
readStream.dispose();
readMemStream.Position = 0;
writeMemStream.Position = 0;
var readArr = readMemStream.ToArray();
var writeArr = writeMemStream.ToArray();
if (!readArr.SequenceEqual(writeArr))
{
System.Console.WriteLine("DIFFERENT");
System.Console.WriteLine(string.Join("",writeArr.Select(q => q.ToString("X2"))));
System.Console.WriteLine(string.Join("",readArr.Select(q => q.ToString("X2"))));
}
else
{
System.Console.WriteLine("SAME");
System.Console.WriteLine(string.Join("",readArr.Select(q => q.ToString("X2"))));
}
解决方法
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。