Подтвердить что ты не робот

Запись битов в файл в C

У меня есть эта строка: "101" Я хочу записать его в файл в C, а не как текст: "101" и так 8 бит x char. но напрямую использовать строку в виде битов: бит "1", бит "0" и бит "1", так что файл будет иметь 3 бита.

Возможно ли это? Я искал в Интернете, и я попытался сделать это:

char c[25] = "101";
FILE *binFile = fopen("binFile.bin", "wb");
int x = atoi(c);
fwrite(&x, sizeof(x), 1, binFile);

Но в конце, когда я проверяю файлы байтов, Windows говорит мне, что это 4-байтовый файл! И не 3bits!

Как я могу это сделать, если это возможно? Большое спасибо.

4b9b3361

Ответ 1

Все файловые системы¹ обрабатывают файлы в байтах (и выделяют пространство для хранения с гораздо большей детализацией, 512 байт за минимальный минимум). Нет никакого способа получить файл длиной 3 бита.

Лучшее, что вы можете сделать, это использовать один общий байт, но игнорировать 5 его бит. Для этого (при условии, что число всегда будет вписываться в байты), преобразуйте входную строку в интегральный тип:

long l = strtol(c, 0, 2);

Затем получите младший байт:

unsigned char b = l & 0xffl;

И напишите его в файл:

fwrite(&b, 1, 1, binFile);

¹ Ну, может быть, не все. Возможно, некоторые исследователи могут экспериментировать с файловыми системами размером в бит. Я не знаю.

Ответ 2

Ваш выходной файл имеет длину 4 байта, потому что вы пишете файл int. На большинстве платформ размер int составляет 4 байта.

Вы не сможете записывать менее 1 байт за раз.

Ответ 3

Что вы можете сделать, это записать его как биты (3) и заполнить его байтом с помощью 0. Однако вам также необходимо запустить (или завершить) число бит (или бит из последнего байта), которые действительно используются.

например. (с использованием первого байта как длины):

00000011   -> 3, meaning from the last (and only byte in this case, 
              only the first 3 bits are used)
10100000   -> 101 is the string, other 5 bits are 0, just use for padding

В этом случае служебные данные первого (длинного) байта составляют 50%, чем длиннее строка, тем меньше процентная ставка.

Ответ 4

2 примечания по вашему подходу:

  • [Современные] Компьютеры не могут обрабатывать менее 1 байта в памяти, поэтому вы не сможете записывать отдельные биты на диск.

    Кроме того, файловые системы обычно выделяют пространство в кусках (512 байт, 1Kb,...), где подходит файл. Итак, если у вас есть файл с 500 байтами, вы фактически теряете 512 байт дискового пространства.

  • atoi() не преобразует из строки в двоичные числа, а в целое. Вы на самом деле пишете 0b1100101, который 0d101. Сначала вы должны выполнить преобразование. Что-то вроде:

    char b = 0;
    for (int i=0; c[i]!=NULL; i++) 
    {
        b = ((b<<1) | atoi(c[i]));
    }
    

Ответ 5

Вы не записываете биты 101, а двоичное значение десятичного числа 101, т.е. 1100101. Поскольку вы fread размером sizeof(x) байтов, ваш файл будет sizeof(x) байтов длиной.