2012-01-19 20 views
14

Estoy usando Ruby 1.9 para abrir varios archivos y copiarlos en un archivo. Ahora hay algunos archivos binarios, pero otros no. Dado que Ruby 1.9 no abre archivos binarios automáticamente como binarios, ¿hay alguna forma de abrirlos automáticamente de todos modos? (Entonces ".class" sería binario, ".txt" no)Abrir automáticamente un archivo como binario con Ruby

Respuesta

30

En realidad, la respuesta anterior de Alex D está incompleta. Si bien es cierto que no hay modo de "texto" en los sistemas de archivos Unix, Ruby no hacer una diferencia entre la apertura de archivos en modo binario y no binario:

s = File.open('/tmp/test.jpg', 'r') { |io| io.read } 
s.encoding 
=> #<Encoding:UTF-8> 

es diferente de (nótese el "rb")

s = File.open('/tmp/test.jpg', 'rb') { |io| io.read } 
s.encoding 
=> #<Encoding:ASCII-8BIT> 

Diga esto, como dice docs, establezca la codificación externa en ASCII-8BIT que le dice a Ruby que no intente interpretar el resultado en UTF-8. Puede lograr lo mismo configurando la codificación explícitamente con s.force_encoding('ASCII-8BIT'). Esta es la clave si desea leer un binario en una cadena y moverlos (por ejemplo, guardarlos en una base de datos, etc.).

2

En las plataformas tipo Unix, no hay diferencia entre abrir archivos en los modos "binario" y "texto". En Windows, el modo "texto" convierte los saltos de línea en estilo DOS, y el modo "binario" no.

A menos que necesite una conversión de línea en plataformas Windows, simplemente abra todos los archivos en modo "binario". No hay daño al leer un archivo de texto en modo "binario".

Si realmente desea distinguir, deberá hacer coincidir File.extname (filename) con una lista de extensiones conocidas como ".txt" y ".class".

+2

Tenga en cuenta que esta respuesta es incorrecta. Ruby lee en una cadena, y desde 1.9 esa cadena tiene una codificación asociada. Consulte la respuesta más modificada para obtener más información e ignórela. Si Alex puede eliminarlo, sería preferible. –

+0

Si lo elimino, la respuesta existente no tendrá sentido ("la respuesta de AlexD ..."). Sería mejor si la información en esta respuesta (mencionando el efecto del indicador 'b' en la conversión de salto de línea) se consolida con la información en el otro primero. –

9

Desde Rubí 1.9.1 hay un método separado para la lectura binaria (IO.binread) y desde 1.9.3 hay uno para la escritura (IO.binwrite), así:

Para la lectura:

content = IO.binread(file) 

para la escritura:

IO.binwrite(file, content) 

Desde IO es la clase padre de File, también se puede hacer lo siguiente WH ich es probablemente más expresivo:

content = File.binread(file) 
File.binwrite(file, content) 
+2

File.binread (file) también es posible – peter

+1

Sí, ya que el padre de la clase 'File' es la clase' IO'. –

Cuestiones relacionadas