Если вам нужны биты, вам необходимо как упаковать, так и распаковать вручную. Ни Ruby, ни какой-либо другой язык общего пользования не сделает это за вас.
Ваш массив содержит строки, которые являются группами символов, но вам нужно построить массив байтов и записать эти байты в файл.
Отсюда: ["010", "1111", "10", "10", "110", "1110", "001", "110", "000", "10", "011"]
вы должны построить эти байты: 01011111 01011011 10001110 00010011
Поскольку это всего четыре байта, вы можете поместить их в один 32-разрядное число, которое 01011111010110111000111000010011
5F5B8E13
шестигранный.
Оба образца вашего кода делают разные вещи. Первый записывает в файл строковое представление массива Ruby. Второй записывает 32 байта, каждый из которых равен 48
('0') или 49
('1').
Если вам нужны биты, размер выходного файла должен быть всего четыре байта.
Подробнее о битовых операциях, чтобы узнать, как этого достичь.
Вот проект. Я не тестировал его. Что-то может быть не так.
a = ["010", "1111", "10", "10", "110", "1110", "001", "110", "000", "10", "011"]
# Join all the characters together. Add 7 zeros to the end.
bit_sequence = a.join + "0" * 7 # "010111110101101110001110000100110000000"
# Split into 8-digit chunks.
chunks = bit_sequence.scan(/.{8}/) # ["01011111", "01011011", "10001110", "00010011"]
# Convert every chunk into character with the corresponding code.
bytes = chunks.map { |chunk| chunk.to_i(2).chr } # ["_", "[", "\x8E", "\x13"]
File.open("my_huffman.bin", 'wb') do |output|
bytes.each { |b| output.write b }
end
Примечание: семь нулей добавляются обрабатывать случай, когда общее количество символов не делится на 8. Без этих нулей, bit_sequence.scan(/.{8}/)
упадет остальные символы.
Что вы хотите, чтобы ваш файл содержал? Персонажи? Или биты? Или массив Ruby? Или что-то другое? –
Биты. Coz Мне нужно меньше размера файла. –
Ответ, вероятно, будет включать использование 'pack' –