Pregunta

De manera informal, la mayoría de nosotros entendemos que hay archivos 'binario' (archivos de objetos, imágenes, películas, archivos ejecutables, los formatos de documentos de propiedad, etc.) y los archivos de 'texto' (código fuente, archivos XML, archivos HTML, correo electrónico, etc. ).

En general, es necesario conocer el contenido de un archivo para ser capaz de hacer algo útil con ella y formar de ese punto de vista si la codificación es 'binario' o 'texto', que en realidad no importa. Y, por supuesto, sólo los archivos almacenan bytes de datos por lo que todos ellos son 'binario' y 'texto' no significa nada sin conocer la codificación. Y, sin embargo, todavía es útil hablar de archivos 'binarios' y 'texto', pero para evitar ofender a nadie con esta definición imprecisa, voy a seguir para usar comillas 'susto'.

Sin embargo, hay varias herramientas que funcionan en una amplia gama de archivos, y en términos prácticos, que desea hacer algo diferente en función de si el archivo es 'texto' o 'binario'. Un ejemplo de esto es cualquier herramienta que da salida a los datos en la consola. Llanura 'texto' se verá muy bien, y es útil. datos 'binario' meta la pata de su terminal, y por lo general no es útil a la vista. grep de GNU, al menos, utiliza esta distinción para determinar si debe partidos de salida a la consola.

Por lo tanto, la pregunta es, ¿cómo saber si un archivo es 'texto' o 'binario'? Y restringir está además, ¿cómo saber en un sistema Linux como sistema de archivos? No estoy al tanto de cualquier meta-datos del sistema de archivos que indica el 'tipo' de un archivo, por lo que la pregunta se vuelve aún más, al inspeccionar el contenido de un archivo, ¿cómo le digo si se trata de 'texto' o 'binario'? Y por simplicidad, permite restringir el 'texto' en el sentido de caracteres que son imprimibles en la consola del usuario. Y en particular, ¿cómo ejecutar esto? (Pensé que esto estaba implícito en este sitio, pero supongo que es útil, en general, a ser señalado en el código existente que hace esto, debería haber especificado), no estoy realmente después de lo que los programas existentes se pueden usar para hacer esto.

¿Fue útil?

Solución

El software de hoja de mi compañía hace que lee un número de formatos de archivos binarios, así como archivos de texto.

En primer lugar, observamos los primeros bytes para una número mágico que reconocer. Si no reconocemos el número mágico de cualquiera de los tipos binarios que leemos, entonces miramos hasta los primeros 2K bytes del archivo para ver si se parece ser un UTF-8 , UTF-16 o un archivo de texto codificado en las href="http://en.wikipedia.org/wiki/Code_page" página de códigos de el sistema operativo anfitrión. Si se aprueba ninguna de estas pruebas, se supone que no es un archivo que podemos tratar y lanzar una excepción apropiada.

Otros consejos

Puede utilizar el comando file. Se hace un montón de pruebas en el archivo (man file) para decidir si es binario o de texto. Usted puede mirar en / prestado su código fuente si es necesario hacerlo desde C.

file README
README: ASCII English text, with very long lines

file /bin/bash
/bin/bash: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), for GNU/Linux 2.2.5, dynamically linked (uses shared libs), stripped

Se puede determinar el tipo MIME del archivo con

file --mime FILENAME

La taquigrafía es file -i en Linux y file -I (capital i) en MacOS (ver comentarios).

Si comienza con text/, es de texto, de otro modo binario. La única excepción son las aplicaciones XML. Puede coincidir con las de buscar +xml al final del tipo de archivo.

Bueno, si sólo están inspeccionando el archivo completo, ver si cada caracter es imprimible con isprint(c). Se pone un poco más complicado para Unicode.

Para distinguir un archivo de texto Unicode, de MSDN ofrece algunas gran consejo en cuanto a qué hacer .

El quid de la cuestión es inspeccionar por primera vez a los cuatro primeros bytes:

EF BB BF     UTF-8 
FF FE        UTF-16, little endian 
FE FF        UTF-16, big endian 
FF FE 00 00  UTF-32, little endian 
00 00 FE FF  UTF-32, big-endian 

Que le dirá la codificación. A continuación, te gustaría usar iswprint(c) para el resto de los caracteres en el archivo de texto. Para UTF-8 y UTF-16, es necesario analizar los datos de forma manual desde un solo carácter puede ser representado por un número variable de bytes. Además, si usted es realmente anal, tendrá que utilizar la variante local de iswprint si eso es disponibles en su plataforma.

Perl tiene una heurística decente. Utilice el operador -B para la prueba de binario (y su opuesto, -T para la prueba de texto). Aquí de Shell una sola línea a la lista de archivos de texto:

$ find . -type f -print0 | perl -0nE 'say if -f and -s _ and -T _'

(Tenga en cuenta que los guiones sin un dólar precedente son correctos (RTFM).)

La mayoría de los programas que tratan de decir la diferencia utilizar una heurística, tales como el examen de los primeros n bytes del archivo y ver si esos bytes todos califica como 'texto' o no (es decir, hacer que todos caen dentro de la gama de charcters ASCII imprimibles). Para distiction más fino siempre existe el comando 'archivo' en los sistemas de tipo UNIX.

Su un viejo tema, pero tal vez alguien va a resultar útil. Si usted tiene que decidir en una secuencia de comandos si algo es un archivo a continuación, sólo tiene que hacer como esto:

if file -i $1 | grep -q text;
then 
.
.
fi

Esto hará que el tipo de archivo, y con un grep silenciosa que puede decidir si es un texto.

Para una lista de nombres de archivo de texto en el directorio actual / subdirectorios:

$ grep -rIl ''

Los binarios:

$ grep -rIL ''

Para comprobar archivo en particular, modificar ligeramente comando:

$ grep -qI '' FILE

A continuación, el código de salida '0' significaría el archivo es un texto; '1' - binario. Podría comprobar:

$ echo $?

Una simple comprobación es si se ha \0 caracteres. Los archivos de texto no tienen ellos.

* nix sistemas operativos indicados anteriormente tienen esta capacidad dentro del comando de archivo. Este comando utiliza un archivo de configuración que define los números mágicos contenidos en muchas estructuras de archivos más populares.

Este archivo, llamado magia se almacenó históricamente en / etc, aunque esto puede estar en / usr / share en algunas distribuciones. La magia archivo define las compensaciones de los valores que se sabe existen en el archivo y luego pueden examinar estos lugares para determinar el tipo de archivo.

La estructura y descripción de la magia archivo se pueden encontrar consultando la página del manual correspondiente (hombre mágico)

En cuanto a la aplicación, así que se pueden encontrar dentro de file.c sí, sin embargo la parte pertinente de la orden de archivo que determina si se trata de un texto legible o no es lo siguiente

/* Make sure we are dealing with ascii text before looking for tokens */
    for (i = 0; i < nbytes - 1; i++) {
        if (!isascii(buf[i]) ||
            (iscntrl(buf[i]) && !isspace(buf[i]) &&
             buf[i] != '\b' && buf[i] != '\032' && buf[i] != '\033'
            )
           )
            return 0;   /* not all ASCII */
    }

Puede utilizar libmagic que es una versión de la biblioteca de la línea de comandos de Unix file.

Hay envoltorio para muchos idiomas:

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top