【问题标题】:SQL CLR Function to decompress GZip data用于解压 GZip 数据的 SQL CLR 函数
【发布时间】:2017-03-26 04:52:15
【问题描述】:

我有两个用于压缩/解压缩 NVARCHAR 数据的 CLR 函数。

[SqlFunction(IsDeterministic = true, IsPrecise = true, DataAccess = DataAccessKind.None)]
public static SqlBytes ufn_GZipCompress(SqlString input) {
    if (input.IsNull || input.Value.Length == 0)
        return SqlBytes.Null;

    using (MemoryStream msInput = new MemoryStream(input.GetUnicodeBytes())) {
        using (MemoryStream msOutput = new MemoryStream()) {
            using (GZipStream deflateStream = new GZipStream(msOutput, CompressionMode.Compress, true)) {
                byte[] buffer = new byte[32768];
                int read;
                while ((read = msInput.Read(buffer, 0, buffer.Length)) > 0)
                    msOutput.Write(buffer, 0, read);
            }

            return new SqlBytes(msOutput.ToArray());
        }
    }
}

[SqlFunction(IsDeterministic = true, IsPrecise = true, DataAccess = DataAccessKind.None)]
public static SqlString ufn_GZipDecompress(SqlBytes input) {
    if (input.IsNull || input.IsNull)
        return SqlString.Null;

    byte[] buf = new byte[32768];

    using (MemoryStream msOutput = new MemoryStream()) {
        using (GZipStream deflateStream = new GZipStream(input.Stream, CompressionMode.Decompress, true)) {
            int bytesRead;
            while ((bytesRead = deflateStream.Read(buf, 0, 32768)) > 0)
                msOutput.Write(buf, 0, bytesRead);
        }

        return new SqlString(Encoding.UTF8.GetString(msOutput.ToArray()));
    }
}

问题是当我尝试解压缩二进制数据时,我没有得到预期的输出,例如:

SELECT dbo.[ufn_GZipDecompress](dbo.[ufn_GZipCompress](N'Hello World'))

返回

H

【问题讨论】:

    标签: c# sql .net sql-server clr


    【解决方案1】:

    我在某个时候正在研究加密 CLR,并记得与此类似的事情,结果证明是编码问题。 sql 的默认SQL_Latin1_General_CP1_CI_ASWindows-1252 编码而不是UTF-8

    我不确定这是否会成为您的 GetUnicodeBytes 以及您返回的编码的问题。您应该测试以确保 input.GetUnicodeBytes() 为您提供所需的结果,我通过重新编译并使用数据引发自定义异常来做到这一点,但我确信其他人有其他方法。

    那么对于你的解压,你可能会尝试这样的事情:

    Encoding enc = Encoding.GetCoding(1252);
    ecn.GetString(yourbytearray)
    

    【讨论】:

    • 这看起来肯定是编码问题。我的猜测是 GetUnicodeBytes() 提供 UTF16 字节,这意味着 UTF8.GetString 会将第一个字符的高位字节解释为空终止符。
    猜你喜欢
    • 1970-01-01
    • 2014-01-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多