微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Flush 和 Write 调用的特定组合会破坏通过 OpenWrite 使用的 BlockBlob 完整代码

如何解决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
  • null 是我调用 Flush 的点
  • 内容可以是任何 - 甚至所有迭代都为零
  • 0xFF、0xAA 仅用于突出显示重复

这里最奇怪的是,如果您在损坏后再写入 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 举报,一经查实,本站将立刻删除。