Ruby - Lesen von bytes aus einer Datei, konvertieren zu integer
Frage
Ich versuche zu Lesen vorzeichenlose Ganzzahlen aus einer Datei (gespeichert als aufeinanderfolgende byte) und konvertieren Sie Sie in ganze zahlen umgewandelt.Ich habe versucht, dies:
file = File.new(filename,"r")
num = file.read(2).unpack("S") #read an unsigned short
puts num #value will be less than expected
Was mache ich hier falsch?
Lösung 4
Ok, ich habe es an der Arbeit:
num = file.read(8).unpack("N")
Vielen Dank für Ihre Hilfe.
Andere Tipps
Sie lesen nicht genug Bytes. Wie Sie im Kommentar zu Tadman Antwort sagen, erhalten Sie 202
statt 3405691582
Beachten Sie, dass die ersten 2 Bytes 0xCAFEBABE
ist 0xCA
= 202
Wenn Sie wirklich alle 8 Bytes in einer einzigen Zahl wollen, dann müssen Sie mehr als die unsigned short
lesenVersuch
num = file.read(8).unpack("L_")
Der Unterstrich wird unter der Annahme, dass die native lange wird 8 Bytes sein, die auf jeden Fall nicht garantiert werden.
Wie wäre es in der Pickaxe suchen? (Ruby 1.9, p. 44)
File.open("testfile")
do |file|
file.each_byte {|ch| print "#{ch.chr}:#{ch} " }
end
each_byte iteriert über eine Datei Byte für Byte.
Es gibt ein paar Bibliotheken, die helfen, mit Binärdaten in Ruby Parsen, indem sie das Datenformat in einer einfachen High-Level-deklarativen DSL erklären und herausfinden, dann wird alle Verpacken, Auspacken, Bit-Fummel, Verschieben und Endian -conversions von selbst.
Ich habe noch nie eine von diesen verwendet, aber hier ist zwei Beispiele. (Es gibt mehr, aber ich kenne sie nicht):
In welchem format sind die zahlen in der Datei gespeichert?Ist es in hex?Ihr code sieht korrekt zu mir.
Wenn Sie mit binären Daten befasst sind, müssen Sie sicher sein, Sie die Datei in Binär-Modus zu öffnen, wenn Sie auf Windows sind. Dies gilt sowohl für das Lesen und Schreiben.
open(filename, "rb") do |file|
num = file.read(2).unpack("S")
puts num
end
Es kann auch Probleme sein mit „Endian“ auf der Source-Plattform abhängig codieren. Zum Beispiel PowerPC-basierte Maschinen, die alten Mac-Systeme umfassen, IBM Power-Server, PS3 Cluster oder Sun Sparc-Servern.
Können Sie ein Beispiel hinterlassen, wie es ist „weniger“? Normalerweise gibt es ein offensichtliches Muster auf die Daten.
Zum Beispiel, wenn Sie 0x1234 wollen, aber Sie bekommen 0x3412 es ist ein Endian-Problem.