我有一些文件,每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