Файл, как его видит большинство ОС, содержит поток байтов, иногда называемых символами. В некоторых системах существует различие между хранением текстовых и двоичных данных (например, PDP-1 использует 6-битные символы и 18-битные слова), но размер файла учитывается в этих байтах. В некоторых системах даже этот уровень не сохраняется, но используется символ конца файла, чтобы отметить, где заканчиваются данные в последнем блоке (будь то сектор, кластер или экстент).
Вам нужно будет повторить один из этих методов для хранения количества битов, например, используя заполнение 1-then-0s . Недостатком этого метода заполнения является то, что вам нужно найти конец, чтобы узнать, образует ли строка 0s (и предыдущий 1) заполнение, а не данные.
Другой метод может заключаться в том, чтобы сначала сохранить количество битов или просто сохранить количество битов для каждого записанного фрагмента. Для этого требуется кодировка, чтобы вы знали размер поля размера, например, один байт, что подразумевало бы фрагменты не более 256 бит. Этот метод префикса длины используется, например, в строки Паскаля .
Вы также можете рассмотреть установленный формат файла, в котором хранятся битовые последовательности, например последовательный векторный формат . Большинство из них не очень эффективны и предназначены для конкретных задач (в данном случае, для хранения временных рядов моделирования цепей).
Подобные схемы также могут быть обобщены в сами форматы хранения данных. Примеры включают в себя строки с префиксом длины , кодовые точки UTF-8 , кодирование BitTorrent или кодирование по экспоненциальному-голомбу . Последний актуален сегодня, поскольку допускает произвольный размер и поддерживается модулем цепочки битов.
Одним из достаточно простых способов в цепочке битов может быть добавление (выровненного) завершающего байта к файлу, указывающего, сколько битов в предпоследнем байте заполнено:
def pad(data: bitstring.BitArray):
padding = data.bytealign()
data.append(bitstring.Bits(chr(padding)))
def unpad(data: bitstring.BitArray):
padding = data[-8:].uint
del data[-8-padding:]
Если вы читаете файл по частям, вам придется позаботиться о том, чтобы выполнить эту операцию, когда вы достигнете последних двух байтов.
Вот вариант 1-затем-0:
def pad(data: bitstring.BitArray):
data.append(bitstring.Bits(length=1, uint=1))
data.bytealign()
def unpad(data: bitstring.BitArray):
last1 = data.rfind(bitstring.Bits(length=1, uint=1))[0]
del data[last1:]