我试图实现“从外部NAV访问压缩Blob”中的代码
但是在 VS2012 中我不断收到 BlobReaderStream 未实现的错误。 不幸的是,在谷歌上搜索没有返回任何结果。看来人们能够按原样使用这段代码,所以一定有一些我缺少的 .NET 库?
你有什么想法?
该帖子的作者在您链接到的页面上提供了“BlobReaderStream”的列表。这是页面上的第二个代码示例。如果您将其纳入您的项目中,您可能会取得更大的成功。
我尝试使用 .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;
}
}