C#的BinaryReader有一个函数,根据MSDN,读取一个编码为“七位整数”的整数,然后读取一个长度为这个整数的字符串。是否有一个明确的文档7位整数格式(我有一个粗略的理解,MSB或LSB标记是否有更多的字节要读取,其余的位是数据,但我很高兴有更确切的东西)。更好的是,是否有C实现来阅读这种格式的数字?
C#
BinaryReader
C
mefy6pfw1#
好吧,BinaryReader.Read7BitEncodedInt的文档已经说明了,它希望用BinaryWriter.Write7BitEncodedInt编写值,并且该方法文档详细说明了格式:value参数的整数从7个最低有效位开始,一次写出7位。一个字节的高位指示在这个字节之后是否还有更多的字节要写入。如果value适合七位,它只占用一个字节的空间。如果值不适合七位,则在第一个字节上设置高位并写出。然后将值移位七位并写入下一字节。重复此过程,直到写入整个整数。因此,整数1259551277(二进制100101100010011001101000101101)将转换为7位格式,如下所示:
Remaining integer encoded bytes 1001011000100110011101000101101 100101100010011001110100 00101101 10010110001001100 10101101 01110100 1001011000 10101101 11110100 01001100 100 10101101 11110100 11001100 01011000 0 10101101 11110100 11001100 11011000 00000100
不过,我现在对我的C技能没有信心来提供一个工作的实现。但根据这个描述,这并不难做到。
kuarbcqp2#
基本上,7位编码Int32背后的想法是减少小值所需的字节数。它的工作原理是这样的:1.取原始值的前7个最低有效位。1.如果该值超过了这7位的值,则第8位被设置为1,表示必须读取另一个字节。否则该位为0,读取到此结束。1.读取下一个字节,其值左移7位,并与先前读取的值进行OR运算以将它们组合在一起。同样,该字节的第8位指示是否必须读取另一个字节(将读取值再移位7次)。1.这将持续到最多读取5个字节为止(因为即使Int32.MaxValue也不需要超过5个字节,当每个字节只窃取1个比特时)。如果第5个字节的最高位仍然被置位,则您读取的不是7位编码的Int32。请注意,由于它是逐字节写入的,因此对于这些值来说,字节顺序根本不重要。给定的值范围需要以下字节数:
Int32
Int32.MaxValue
Int32.MinValue
正如你所看到的,这个实现有点愚蠢,总是需要5个字节来表示负值,因为符号位是原始值的第32位,总是在第5个字节结束。因此,我不建议使用负值或大于~250,000,000的值。我只看到它在内部用于. NET字符串的字符串长度前缀(那些你可以用BinaryReader.ReadString和BinaryReader.WriteString读/写的字符串),描述字符串组成的字符数,只有正值。虽然您可以查找原始的. NET源代码,但我在BinaryData库中使用了不同的实现。
BinaryReader.ReadString
BinaryReader.WriteString
uhry853o3#
我也不得不探索这个7位格式。在我的一个项目中,我使用C#的BinaryWriter将一些数据打包到文件中,然后使用BinaryReader再次解包,它工作得很好。后来我还需要为这个项目的Java打包文件实现一个阅读器。Java有一个名为DataInputStream的类(在java.io包中),它有一些类似的方法。不幸的是,DataInputStream的数据解释与C#的非常不同。为了解决我的问题,我通过编写一个扩展java.io.DataInputStream的类,将C#的BinaryReader移植到Java中。下面是我写的方法,它的作用与C#的BinaryReader.readString()完全相同:
public String csReadString() throws IOException { int stringLength = 0; boolean stringLengthParsed = false; int step = 0; while(!stringLengthParsed) { byte part = csReadByte(); stringLengthParsed = (((int)part >> 7) == 0); int partCutter = part & 127; part = (byte)partCutter; int toAdd = (int)part << (step*7); stringLength += toAdd; step++; } char[] chars = new char[stringLength]; for(int i = 0; i < stringLength; i++) { chars[i] = csReadChar(); } return new String(chars); }
f0ofjuux4#
/* * Parameters: plOutput[out] - The decoded integer * pbyInput[in] - Buffer containing encoded integer * Returns: Number of bytes used to encode the integer */ int SevenBitEncodingToInteger(int *plOutput, char *pbyInput) { int lSize = 0; int lTemp = 0; while(true) { lTemp += pbyInput[lSize] & 0x7F; if(pbyInput[lSize++] > 127) lTemp <<= 7; else break; } *plOutput = lTemp; return lSize; }
dced5bon5#
格式如下所述:http://msdn.microsoft.com/en-us/library/system.io.binarywriter.write7bitencodedint.aspx
jk9hmnmh6#
Write7BitEncodedInt方法包含描述:每个字节的最低7位编码数字的下7位。当后面有另一个字节时,最高位被置位。
6条答案
按热度按时间mefy6pfw1#
好吧,BinaryReader.Read7BitEncodedInt的文档已经说明了,它希望用BinaryWriter.Write7BitEncodedInt编写值,并且该方法文档详细说明了格式:
value参数的整数从7个最低有效位开始,一次写出7位。一个字节的高位指示在这个字节之后是否还有更多的字节要写入。
如果value适合七位,它只占用一个字节的空间。如果值不适合七位,则在第一个字节上设置高位并写出。然后将值移位七位并写入下一字节。重复此过程,直到写入整个整数。
因此,整数1259551277(二进制100101100010011001101000101101)将转换为7位格式,如下所示:
不过,我现在对我的C技能没有信心来提供一个工作的实现。但根据这个描述,这并不难做到。
kuarbcqp2#
基本上,7位编码
Int32
背后的想法是减少小值所需的字节数。它的工作原理是这样的:1.取原始值的前7个最低有效位。
1.如果该值超过了这7位的值,则第8位被设置为1,表示必须读取另一个字节。否则该位为0,读取到此结束。
1.读取下一个字节,其值左移7位,并与先前读取的值进行OR运算以将它们组合在一起。同样,该字节的第8位指示是否必须读取另一个字节(将读取值再移位7次)。
1.这将持续到最多读取5个字节为止(因为即使
Int32.MaxValue
也不需要超过5个字节,当每个字节只窃取1个比特时)。如果第5个字节的最高位仍然被置位,则您读取的不是7位编码的Int32。请注意,由于它是逐字节写入的,因此对于这些值来说,字节顺序根本不重要。给定的值范围需要以下字节数:
Int32.MaxValue
)和-2,147,483,648(Int32.MinValue
)到-1\f2正如你所看到的,这个实现有点愚蠢,总是需要5个字节来表示负值,因为符号位是原始值的第32位,总是在第5个字节结束。
因此,我不建议使用负值或大于~250,000,000的值。我只看到它在内部用于. NET字符串的字符串长度前缀(那些你可以用
BinaryReader.ReadString
和BinaryReader.WriteString
读/写的字符串),描述字符串组成的字符数,只有正值。虽然您可以查找原始的. NET源代码,但我在BinaryData库中使用了不同的实现。
uhry853o3#
我也不得不探索这个7位格式。在我的一个项目中,我使用C#的BinaryWriter将一些数据打包到文件中,然后使用BinaryReader再次解包,它工作得很好。
后来我还需要为这个项目的Java打包文件实现一个阅读器。Java有一个名为DataInputStream的类(在java.io包中),它有一些类似的方法。不幸的是,DataInputStream的数据解释与C#的非常不同。
为了解决我的问题,我通过编写一个扩展java.io.DataInputStream的类,将C#的BinaryReader移植到Java中。下面是我写的方法,它的作用与C#的BinaryReader.readString()完全相同:
f0ofjuux4#
dced5bon5#
格式如下所述:http://msdn.microsoft.com/en-us/library/system.io.binarywriter.write7bitencodedint.aspx
jk9hmnmh6#
Write7BitEncodedInt方法包含描述:每个字节的最低7位编码数字的下7位。当后面有另一个字节时,最高位被置位。