我有一些文件,每7位代表一个little-endian整数。如何以整数形式读取文件中的每7位?
到目前为止,我有一个实现将字节读入字节数组,转换为字符串,使用循环索引将7个字符放入BitArray,并根据索引做2^x,但这似乎非常缓慢(文件只有20KB,但需要5分钟才能解析),而且太多的文件是最好的方式。
有没有办法直接从文件中读取一组7位数据?
我有一些文件,每7位代表一个little-endian整数。如何以整数形式读取文件中的每7位?
到目前为止,我有一个实现将字节读入字节数组,转换为字符串,使用循环索引将7个字符放入BitArray,并根据索引做2^x,但这似乎非常缓慢(文件只有20KB,但需要5分钟才能解析),而且太多的文件是最好的方式。
有没有办法直接从文件中读取一组7位数据?
如果这7位整数没有包装,那么它的每个字节的最低显著7位工作的一个简单的问题:
Byte b; Int32 nb;
while((nb = reader.ReadByte()) != -1) {
b = (Byte)nb;
Byte value = b & 0x7F;
yield return value;
}
如果这些都挤满字节,那么它的更多的乐趣:)
您将需要1到2个字节来处理,从中提取值。我假设输入的Byte
(为简单起见API使用IEnumerator
表示)流,其中7位被打包像这样:
7-bit |0 |1 |2 |3 |4
Bytes |0 |1 |2 |3
Bits |0 |1 |2 |3 |4 |5 |6 |7 |0 |1 |2 |3 |4 |5 |6 |7 |0 |1 |2 |3 |4 |5 |6 |7 |0
该算法是这样的:
bi
),告诉我们下一个7位整数开始的位偏移量(在每个字节中)。b0
),取前7位并返回。b1
)与前一个字节(b0
)合并为一个可一次读取的16位值bi + 7
)来提取下一个7位值,把它变成有用的,然后让它返回。这里可能有一些错误,让我知道如果你找到任何!
public static IEnumerable<Byte> ReadPacked7BitInts(IEnumerator<Byte> inputBytes) {
Int32 bi = 0; // bit-index
if(!inputBytes.MoveNext()) yield break;
Byte b0 = inputBytes.Current;
while(true) {
if(bi == 0) yield return b0 & 0x7F;
if(bi == 1) yield return (b0 >> 1) & 0x7F;
else {
// Read another byte
if(!inputBytes.MoveNext()) yield break;
Byte b1 = inputBytes.Current;
UInt16 value = (UInt16)b0 | ((UInt16)b1 << 8);
yield return (value >> bi) & 0x7F;
}
bi = (bi + 7) % 8;
}
}
如果这就是你的乐趣的想法,我远离任何你抛出的派对;) – BradleyDotNET 2015-03-02 23:57:19
你应该在循环内将下一步移动到if(!inputBytes.MoveNext())yield break;'(还有其他的需要修复的小东西,像其他'return;'需要切换到'yield break';'int'和'byte'和'UInt16'之类的东西之间的一些铸造错误) – 2015-03-02 23:59:59
@ScottChamberlain固定!感谢您指出这些。 – Dai 2015-03-03 00:51:33
我感到非常,非常,对不起,你 – BradleyDotNET 2015-03-02 23:19:47
这是一个** **包装7位(因此位0-6是第一个整数,则位7-14是第二个整数),或这是一个7位保留系统(所以位0-6是第一个整数,位7被忽略,位8-15是以下整数)? – Dai 2015-03-02 23:23:40
你可以编辑你的问题,向我们展示你到目前为止的代码吗?你有没有考虑过使用[profiler](http://www.red-gate.com/products/dotnet-development/ants-performance-profiler/)来告诉你瓶颈在哪里? – 2015-03-02 23:23:46