Ruby - считывает байты из файла, преобразует в целое число
Вопрос
Я пытаюсь прочитать целые числа без знака из файла (хранящегося в виде последовательного байта) и преобразовать их в целые числа.Я уже пробовал это:
file = File.new(filename,"r")
num = file.read(2).unpack("S") #read an unsigned short
puts num #value will be less than expected
Что я здесь делаю не так?
Решение 4
Хорошо, у меня получилось:
num = file.read(8).unpack("N")
Спасибо за всю вашу помощь.
Другие советы
Вы читаете недостаточно байтов.Как вы говорите в комментарии к ответу тадмана, вы получаете 202
вместо того, чтобы 3405691582
Обратите внимание, что первые 2 байта 0xCAFEBABE
является 0xCA
= 202
Если вы действительно хотите, чтобы все 8 байт были в одном числе, то вам нужно прочитать больше, чем беззнаковое короткое
попробуй
num = file.read(8).unpack("L_")
Подчеркивание предполагает, что исходная длина будет составлять 8 байт, что определенно не гарантируется.
Как насчет того, чтобы заглянуть в Кирку?(Ruby 1.9, стр.44)
File.open("testfile")
do |file|
file.each_byte {|ch| print "#{ch.chr}:#{ch} " }
end
each_byte выполняет итерацию по файлу байт за байтом.
Есть пара библиотек, которые помогают с синтаксическим анализом двоичных данных в Ruby, позволяя вам объявлять формат данных в простом высокоуровневом декларативном DSL, а затем самостоятельно выполнять все операции упаковки, распаковки, перебора битов, сдвига и преобразования в конце.
Я никогда не использовал ни один из них, но вот два примера.(Есть и другие, но я их не знаю):
В каком формате хранятся числа в файле?Это на шестнадцатеричном языке?Мне ваш код кажется правильным.
При работе с двоичными данными вы должны быть уверены, что открываете файл в двоичном режиме, если вы используете Windows.Это относится как к чтению, так и к письму.
open(filename, "rb") do |file|
num = file.read(2).unpack("S")
puts num
end
Также могут возникнуть проблемы с кодировкой "endian" в зависимости от исходной платформы.Например, компьютеры на базе PowerPC, которые включают старые системы Mac, серверы IBM Power, кластеры PS3 или серверы Sun Sparc.
Можете ли вы привести пример того, насколько это "меньше"?Обычно в данных присутствует очевидная закономерность.
Например, если вы хотите 0x1234, но получаете 0x3412, это проблема с окончанием.