texto que los hacen guardar generar ejemplos binarios binario archivos archivo unix language-agnostic ascii binaryfiles file-format

unix - que - ¿Cómo distingo entre archivos ''binarios'' y ''textos''?



guardar en archivo binario c (11)

Bueno, si solo está inspeccionando el archivo completo, vea si cada carácter es imprimible con isprint(c) . Se vuelve un poco más complicado para Unicode.

Para distinguir un archivo de texto Unicode, MSDN ofrece algunos excelentes consejos sobre qué hacer .

Lo esencial es primero inspeccionar hasta los primeros cuatro 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

Eso te dirá la codificación. Luego, querrá usar iswprint(c) para el resto de los caracteres en el archivo de texto. Para UTF-8 y UTF-16, debe analizar manualmente los datos, ya que un solo carácter puede representarse mediante un número variable de bytes. Además, si eres realmente anal, querrás usar la variante de configuración regional de iswprint si está disponible en tu plataforma.

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

En general, necesitas saber el contenido de un archivo para poder hacer algo útil con él, y formar ese punto de vista si la codificación es ''binaria'' o ''texto'', realmente no importa. Y, por supuesto, los archivos solo almacenan bytes de datos para que sean todos ''binarios'' y ''texto'' no significa nada sin conocer la codificación. Y, sin embargo, todavía es útil hablar sobre archivos ''binarios'' y ''de texto'', pero para evitar ofender a nadie con esta definición imprecisa, continuaré usando citas ''de susto''.

Sin embargo, hay varias herramientas que funcionan en una amplia gama de archivos, y en términos prácticos, desea hacer algo diferente según si el archivo es ''texto'' o ''binario''. Un ejemplo de esto es cualquier herramienta que muestre datos en la consola. El ''texto'' sencillo se verá bien y es útil. Los datos ''binarios'' estropean su terminal y, en general, no son útiles para mirar. GNU grep al menos usa esta distinción para determinar si debería generar coincidencias con la consola.

Entonces, la pregunta es, ¿cómo se puede decir si un archivo es ''texto'' o ''binario''? Y para restringir es más, ¿cómo se puede decir en un sistema de archivos como Linux? No conozco ningún metadato del sistema de archivos que indique 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 puedo saber si es ''texto'' o ''binario''? Y para simplificar, permitamos que "texto" restrinja los caracteres que se pueden imprimir en la consola del usuario. Y, en particular, ¿cómo implementarías esto? (Pensé que esto estaba implícito en este sitio, pero creo que es útil, en general, apuntar al código existente que hace esto, debería haberlo especificado), realmente no estoy buscando qué programas existentes puedo usar para hacer esta.


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

Este archivo, llamado magic, se almacenó históricamente en / etc, aunque puede estar en / usr / share en algunas distribuciones. El archivo mágico define compensaciones de valores conocidos que existen dentro del archivo y luego puede examinar estas ubicaciones para determinar el tipo de archivo.

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

En cuanto a una implementación, bien que se puede encontrar dentro de file.c mismo, sin embargo, la parte relevante del comando de archivo que determina si es texto legible o no es la 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 */ }


El software de hoja de cálculo que hace mi empresa lee una cantidad de formatos de archivo binarios y también archivos de texto.

Primero miramos los primeros bytes para un número mágico que reconocemos. Si no reconocemos el número mágico de cualquiera de los tipos binarios que leemos, entonces buscamos hasta los primeros 2K bytes del archivo para ver si parece ser un UTF-8 , UTF-8 o un archivo de texto codificado en la página de códigos actual del sistema operativo host. Si no pasa ninguna de estas pruebas, suponemos que no se trata de un archivo que podamos tratar y arroje una excepción adecuada.


Es un tema viejo, pero tal vez alguien lo encuentre útil. Si tiene que decidir en un script si algo es un archivo, simplemente puede hacer esto:

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

Esto obtendrá el tipo de archivo, y con un grep silencioso puede decidir si es un texto.


La mayoría de los programas que intentan diferenciar usan una heurística, como examinar los primeros n bytes del archivo y ver si esos bytes califican como ''texto'' o no (es decir, todos caen dentro del rango de charcters ASCII imprimibles) . Para obtener una mejor definición, siempre existe el comando ''file'' en los sistemas tipo UNIX.


Para listar nombres de archivos de texto en dir / subdirectos actuales:

$ grep -rIl ''''

Binarios:

$ grep -rIL ''''

Para verificar un archivo en particular, modifique ligeramente el comando:

$ grep -qI '''' FILE

entonces, el estado de salida ''0'' significaría que el archivo es un texto; ''1'' - binario. Podría verificar:

$ echo $?


Perl tiene una heurística decente. Use el operador -B para probar el binario (y su opuesto, -T para probar el texto). Aquí está el shell de una línea para listar archivos de texto:

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

(Tenga en cuenta que esos guiones bajos sin un dólar anterior son correctos (RTFM).)


Puede determinar el tipo MIME del archivo con

file --mime FILENAME

La abreviatura es file -i en Linux y file -I (capital i) en macOS (ver comentarios).

Si comienza con text/ , es texto, de lo contrario binario. La única excepción son las aplicaciones XML. Puede encontrarlos buscando +xml al final del tipo de archivo.


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

Hay envoltorio para muchos idiomas:


Una simple comprobación es si tiene /0 caracteres. Los archivos de texto no los tienen.


Puedes usar el comando de file . Hace un montón de pruebas en el archivo ( man file ) para decidir si es binario o de texto. Puede ver / tomar prestado su código fuente si necesita hacer eso 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