我在h-base表的行中有一个限定符(长值类型)。
我想取两个长数字中间的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时,这些过滤器工作正常,但如果数字大于此数字,则会失败。
我在调试时发现,在将长数字转换为字节数组时,它返回的字节数组类似于\0\0\0\0\0\1\128。
当字节数组中的最后一个数字为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)
提前谢谢。
1条答案
按热度按时间qcuzuvrc1#
utf8不是将任意字节编码为字符串的合适方法。相反:它将任意字符串编码为字节(反之亦然,只要字节的格式正确)。没有理由这么想
HBaseGenericHelper.GetBigEndianByteArray(startEpochInDays)
返回utf-8数据,所以encoding.GetString
是完全不合适的,实际上是在使用Encoding
向后的。这是我在这里讨论的第一个主题-所以不要惊慌:你的公司很好-人们总是犯这个错误。您应该使用的是base-16(十六进制)或base-64。
要获得十六进制:
BitConverter.ToString(byte[])
. 要获得base-64:Convert.ToBase64String(byte[])
如果您需要数据的格式不是base-64或base-16,那么您必须明确指定所需的格式。但是:它不是“utf-8反用”。