UTF-8 不适用于将 byte[] 转换为字符串
UTF-8 is not working for converting byte[] to string
我在 H-Base 的行中有一个限定符(长值类型)table。
我想获取两个长数字之间的 H-Base 行。为此,我使用了以下过滤器。
我的过滤器是这样的:
long startEpochInDay = 384;
long endEpochInDays = 396;
string startDayFilter = "SingleColumnValueFilter('" + cf + "','" + qualifier + "', >= ,'binary:" + Encoding.UTF8.GetString(HBaseGenericHelper.GetBigEndianByteArray(startEpochInDays)) + "',true,true)";
string endDayFilter = "SingleColumnValueFilter('" + cf + "','" + qualifier + "', < ,'binary:" + Encoding.UTF8.GetString(HBaseGenericHelper.GetBigEndianByteArray(endEpochInDays)) + "',true,true)";
string finalFilter = startDayFilter + " AND " + endDayFilter
这些过滤器在数字小于 383 时工作正常,但如果数字大于此数字则失败。
我在将长数字转换为字节数组进行调试时发现它 returns 字节数组像 [=51=][=51=][=51=][=51=][=51=][=51=]8 .
当字节数组中的最后一个数字为 127 或更少时,UTF-8 工作正常,但当此数字变为 128 或大于该数字时,UTF-8 开始返回 "?" 最后一位数字。
如果我使用以下方法将字节数组编码为字符串
Encoding encoding = new UTF8Encoding(true,true);
string number = encoding.GetString(HBaseGenericHelper.GetBigEndianByteArray(startEpochInDays));
UTF-8 在将字节数组(如果字节数组中的最后一位数字为 128 或更多)转换为过滤器中的字符串时抛出异常。
异常 - 无法将索引 6 处的字节 [8B] 从指定代码页转换为 Unicode。
内部异常 -
at System.Text.DecoderExceptionFallbackBuffer.Throw(Byte[] bytesUnknown, Int32 index)
at System.Text.DecoderExceptionFallbackBuffer.Fallback(Byte[] bytesUnknown, Int32 index)
at System.Text.DecoderFallbackBuffer.InternalFallback(Byte[] bytes, Byte* pBytes)
at System.Text.UTF8Encoding.GetCharCount(Byte* bytes, Int32 count, DecoderNLS baseDecoder)
at System.String.CreateStringFromEncoding(Byte* bytes, Int32 byteLength, Encoding encoding)
at System.Text.UTF8Encoding.GetString(Byte[] bytes, Int32 index, Int32 count)
at System.Text.Encoding.GetString(Byte[] bytes)
提前致谢。
UTF8 不是将任意字节编码为字符串的合适方法。相反:它将任意字符串编码为字节(反之亦然,只要字节的格式正确)。没有理由认为 HBaseGenericHelper.GetBigEndianByteArray(startEpochInDays)
returns UTF-8 数据,所以 encoding.GetString
是完全不合适的,实际上是在使用 Encoding
backwards.这就是 first topic I discussed here - 所以不要惊慌:你们是好伙伴 - 人们总是 犯这个错误。
您应该使用 base-16(十六进制)或 base-64 之类的东西。
获取十六进制:BitConverter.ToString(byte[])
。要获得 base-64:Convert.ToBase64String(byte[])
如果您需要数据采用 base-64 或 base-16 以外的特定格式,则必须具体说明所需的格式。但是:它不是 "UTF-8 used backwards".
我在 H-Base 的行中有一个限定符(长值类型)table。
我想获取两个长数字之间的 H-Base 行。为此,我使用了以下过滤器。
我的过滤器是这样的:
long startEpochInDay = 384;
long endEpochInDays = 396;
string startDayFilter = "SingleColumnValueFilter('" + cf + "','" + qualifier + "', >= ,'binary:" + Encoding.UTF8.GetString(HBaseGenericHelper.GetBigEndianByteArray(startEpochInDays)) + "',true,true)";
string endDayFilter = "SingleColumnValueFilter('" + cf + "','" + qualifier + "', < ,'binary:" + Encoding.UTF8.GetString(HBaseGenericHelper.GetBigEndianByteArray(endEpochInDays)) + "',true,true)";
string finalFilter = startDayFilter + " AND " + endDayFilter
这些过滤器在数字小于 383 时工作正常,但如果数字大于此数字则失败。
我在将长数字转换为字节数组进行调试时发现它 returns 字节数组像 [=51=][=51=][=51=][=51=][=51=][=51=]8 .
当字节数组中的最后一个数字为 127 或更少时,UTF-8 工作正常,但当此数字变为 128 或大于该数字时,UTF-8 开始返回 "?" 最后一位数字。
如果我使用以下方法将字节数组编码为字符串
Encoding encoding = new UTF8Encoding(true,true);
string number = encoding.GetString(HBaseGenericHelper.GetBigEndianByteArray(startEpochInDays));
UTF-8 在将字节数组(如果字节数组中的最后一位数字为 128 或更多)转换为过滤器中的字符串时抛出异常。
异常 - 无法将索引 6 处的字节 [8B] 从指定代码页转换为 Unicode。
内部异常 -
at System.Text.DecoderExceptionFallbackBuffer.Throw(Byte[] bytesUnknown, Int32 index)
at System.Text.DecoderExceptionFallbackBuffer.Fallback(Byte[] bytesUnknown, Int32 index)
at System.Text.DecoderFallbackBuffer.InternalFallback(Byte[] bytes, Byte* pBytes)
at System.Text.UTF8Encoding.GetCharCount(Byte* bytes, Int32 count, DecoderNLS baseDecoder)
at System.String.CreateStringFromEncoding(Byte* bytes, Int32 byteLength, Encoding encoding)
at System.Text.UTF8Encoding.GetString(Byte[] bytes, Int32 index, Int32 count)
at System.Text.Encoding.GetString(Byte[] bytes)
提前致谢。
UTF8 不是将任意字节编码为字符串的合适方法。相反:它将任意字符串编码为字节(反之亦然,只要字节的格式正确)。没有理由认为 HBaseGenericHelper.GetBigEndianByteArray(startEpochInDays)
returns UTF-8 数据,所以 encoding.GetString
是完全不合适的,实际上是在使用 Encoding
backwards.这就是 first topic I discussed here - 所以不要惊慌:你们是好伙伴 - 人们总是 犯这个错误。
您应该使用 base-16(十六进制)或 base-64 之类的东西。
获取十六进制:BitConverter.ToString(byte[])
。要获得 base-64:Convert.ToBase64String(byte[])
如果您需要数据采用 base-64 或 base-16 以外的特定格式,则必须具体说明所需的格式。但是:它不是 "UTF-8 used backwards".