Как сохранить большие массивы логических значений в файле с самым легким размером?

Моя программа производит большие массивы, заполненные логическими значениями. Мне нужен самый компактный способ сохранить их в файл.

Я прочитал здесь http://www.kirupa.com/forum/showthread.php?339670-How-is-boolean-represented-in-memory что 8 логических значений в памяти могут быть представлены как один байт, поэтому один логический тип - это один бит. Но как я могу сохранить эти массивы с булевыми значениями в компактном файле? Я знаю - функции записи в файл работают с байтами, а не с битами.

Коротко - я хочу иметь возможность сохранять массивы логических значений в файл, размер которого в 8 раз меньше, чем у Array.Length

1 ответ

Решение

Я полагаю, что вы пишете код на C++, поскольку размещенная вами ссылка ведет на форум C++?

Вы можете использовать битовые маски и битовые операции, где каждый логический элемент расположен в определенном бите вашего байта. Следовательно, вы можете использовать один байт (uint8) для хранения 8 логических значений. Это довольно низкий уровень, и я делал это при кодировании на C и там, где хранилище было большой проблемой.

Если вы действительно хотите пойти по этому пути, вам лучше скрыть операции ниже в некоторых функциях чтения / записи и установки / сброса более высокого уровня. После преобразования ваших логических значений в байты (теперь у вас есть массив байтов!), Вы можете просто записать их в двоичные файлы, как описано здесь.

Вот несколько советов о том, как логические значения могут быть преобразованы в байты: вы создаете маски для каждого интересующего вас логического значения, чтобы указать, в каком месте байта они будут записываться / считываться.

Я использую шестнадцатеричные числа для лучшей читаемости.

Например:

uint8 bitFlags = 0x00; // empty mask  0000 0000

uint8 maskA = 0x01;    // first bit:  0000 0001
uint8 maskB = 0x02;    // second bit: 0000 0010

Чтобы установить переменную, используйте побитовое ИЛИ (сохраняет все остальные биты, но устанавливает интересующий вас бит:

bitFlags = bitFlags | maskA;

Прочитайте переменную:

bool isTrueA = ( bitFlags & maskA ) > 0 ; // bitwise AND, result is 1 if bit is set, 
                                          // 0 otherwise

Сбросить переменную:

bitFlags = bitFlags & (!maskA);           // bitwise AND with inverse mask: 1111 1110
                                          // forces position of A to be zero

Более подробную информацию об использовании битовых масок можно найти здесь.

Другие вопросы по тегам