2009-06-02 28 views
25

¿Existe alguna forma sencilla de escribir datos binarios en un archivo binario como solíamos hacer en C/C++? Por ejemplo, ¿cómo puedo crear un archivo de 4 bytes con un valor entero serializado de 4 bytes sin usar cálculos sofisticados?Escribir archivo binario en Ruby

Respuesta

29

Puede usar Array#pack y String#unpack para realizar conversiones hacia y desde representaciones binarias. Combínelos con IO#write y IO#read, y listo.

+0

Sí, creo que la tuya es la mejor respuesta para esta pregunta en particular. +1 –

+0

Gracias por responder, esto funcionó para mí. –

+3

Esto parece lo que quiero hacer, pero todavía no sé cómo hacerlo. ¿Qué formato debo desempaquetar una cadena binaria usando 'String # unpack'? – mehulkar

3

Hay Marshal.dump y Marshal.load métodos que puede utilizar.

Aquí hay un enlace: http://en.wikipedia.org/wiki/Serialization#Ruby.

y otro que guarda los datos en un archivo: http://rubylearning.com/satishtalim/object_serialization.html.

+0

Esto funciona bien, pero todavía no pudo obtener el archivo de 4 bytes utilizando la siguiente: File.open ('test.bin', 'wb') {| archivo | archivo << Marshal.dump (12345)}, obtengo un archivo de 6 bytes. El problema es que necesito crear un archivo binario de formato propietario, este archivo consta de registros, cada uno de ellos es de longitud fija, registro de estilo C con números enteros, bytes, etc. Gracias por la respuesta realmente rápida. –

+0

Sin preocupaciones. La respuesta de Pesto parece muy prometedora. –

0

En mi humilde opinión, ruby ​​no fue hecho para tales tareas. Si tiene que escribir mucho en archivos binarios, sería más fácil escribir algunas funciones c para eso y llamarlas desde ruby, lo cual es bastante fácil usando swig. Estoy haciendo lo mismo en este momento para escribir un simulador de redadas.

+0

Correcto, probablemente Ruby estaba destinado a otras cosas, pero ya tenemos una aplicación de Rails bastante grande y acabamos de enfrentar esta necesidad de operar con archivos binarios. Sin embargo, gracias por su respuesta, podríamos considerar escribir la extensión nativa en C/C++. –

+0

El problema con la escritura de esas funciones en C/C++ es que si lo hace, podría vincularlas a una implementación específica de Ruby. Ver http://stackoverflow.com/questions/3292610/what-version-of-ruby/3294275#3294275 – sampablokuper

21

Recientemente tuve un problema similar para el trabajo. Usé la gema BinData y funcionó bien. Usted acaba de hacer algo como:

File.open('test.bin', 'wb') {|file| BinData::Int32be.new(12345).write(file) } 

y que no es necesario recordar los códigos de Array#pack.

+0

¡Gracias! ¡Excelente! Ahora tengo curiosidad de cómo se implementa en la gema ... –

+0

la gema está haciendo el embalaje/desembalaje. código fuente [aquí] (https://github.com/dmendel/bindata). como dice la respuesta, simplemente evita que tengas que recordar cómo/qué códigos de paquete usar – Andrea

Cuestiones relacionadas