从 C# 外部读取 NAV 压缩的 blob blob

问题描述 投票:0回答:2

我试图实现“从外部NAV访问压缩Blob”中的代码

但是在 VS2012 中我不断收到 BlobReaderStream 未实现的错误。 不幸的是,在谷歌上搜索没有返回任何结果。看来人们能够按原样使用这段代码,所以一定有一些我缺少的 .NET 库?

你有什么想法?

c#
2个回答
0
投票

该帖子的作者在您链接到的页面上提供了“BlobReaderStream”的列表。这是页面上的第二个代码示例。如果您将其纳入您的项目中,您可能会取得更大的成功。


0
投票

我尝试使用 .net 7.0 中发布的文章中编写的类(启用了 4/2024 的 C# 预览语言功能),但遇到了问题。经过一番辛苦、尝试和错误,我得到了以下结果。

public class NAVBlobReader
{
    private static readonly byte[] BlobMagic = [2, 69, 125, 91];
    
    /// <summary>Gets decompressed stream from Navision, excluding the blob magic bytes.</summary>
    /// <param name="buffer">The buffer.</param>
    /// <returns>The decompressed stream (or null if validation failed).</returns>
    public static MemoryStream? outStream GetDecompressedStream(byte[] buffer)
    {
        if (buffer.Length <= 4)
        {
            // A valid NAV blob would always be more than 4 bytes
            return null;
        }
        var array = new[] { buffer[0], buffer[1], buffer[2], buffer[3] };
        if (!BlobMagicOk(array))
        {
            // A valid NAV blob would always have the first four bytes
            // match the "magic numbers"
            return null;
        }
        // Skip the magic numbers and take the rest for decompression
        using var inStream = new MemoryStream(buffer.Skip(4).ToArray());
        var outStream = new MemoryStream();
        using (var decompressor = new DeflateStream(
            inStream,
            CompressionMode.Decompress))
        {
            decompressor.CopyTo(outStream);
        }
        // The outStream should now be flush with the proper bytes
        // which can be converted to a string using (usually) UTF8
        return outStream;
    }

    /// <summary>Compress string for Navision storage.</summary>
    /// <param name="source">The source string.</param>
    /// <returns>A byte[] which has the four NAV blob magic bytes and is compressed using Deflate.</returns>
    public static byte[] CompressStringForNavStorage(string source)
    {
        List<byte> input = [..BlobMagic];
        input.AddRange(Encoding.UTF8.GetBytes(source));
        using var inStream = new MemoryStream(input.ToArray());
        using var outStream = new MemoryStream();
        using (var compressor = new DeflateStream(
            outStream,
            CompressionMode.Compress))
        {
            inStream.CopyTo(compressor);
        }
        // Now that the compressor has closed, the outStream has the bytes.
        // It MUST close the stream or DeflateStream won't flush it's contents
        return outStream.GetBuffer();
    }

    /// <summary>BLOB magic ok.</summary>
    /// <param name="checkMagic">The check magic.</param>
    /// <returns>True if it succeeds, false if it fails.</returns>
    private static bool BlobMagicOk(IReadOnlyList<byte> checkMagic)
    {
        for (var i = 0; i < 4; i++)
        {
            if (checkMagic[i] != BlobMagic[i])
            {
                return false;
            }
        }
        return true;
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.