Question

Officieusement, la plupart d'entre nous comprennent qu'il ya des fichiers « binaires » (fichiers d'objets, des images, des films, executables, formats de documents propriétaires, etc.) et les fichiers « texte » (code source, fichiers XML, fichiers HTML, le courrier électronique, etc. ).

En général, vous devez connaître le contenu d'un fichier pour être en mesure de faire quelque chose d'utile, et former ce point de vue si l'encodage est « binaire » ou « texte », il n'a pas vraiment d'importance. Et les fichiers cours stockent simplement octets de données de sorte qu'ils sont tous « binaires » et « texte » ne signifie rien sans connaître le codage. Et pourtant, il est toujours utile de parler de fichiers « binaires » et « texte », mais pour éviter d'offenser qui que ce soit avec cette définition imprécise, je continue à utiliser des citations « alarmistes ».

Cependant, il existe différents outils qui fonctionnent sur un large éventail de dossiers, et en pratique, vous voulez faire quelque chose de différent selon que le fichier est « texte » ou « binaire ». Un exemple de ceci est un outil qui génère des données sur la console. « Text » ordinaire regardera bien, et est utile. données « binaires » bousille votre terminal, et est généralement pas utile d'examiner. GNU grep utilise au moins cette distinction pour déterminer si elle doit les matches de sortie à la console.

Alors, la question est, comment voulez-vous dire si un fichier est « texte » ou « binaire »? Et pour limiter est encore, comment voulez-vous dire sur un Linux comme système de fichiers? Je ne suis pas au courant d'aucune méta-données du système de fichiers qui indique le « type » d'un fichier, la question plus devient, en examinant le contenu d'un fichier, comment puis-je savoir s'il est « texte » ou « binaire »? Et pour plus de simplicité, permet de limiter « texte » pour désigner les caractères qui sont imprimables sur la console de l'utilisateur. Et surtout comment vous mettre en œuvre ce? (Je pensais que cela impliquait sur ce site, mais je pense qu'il est utile, en général, à signaler au code existant qui fait cela, je l'ai spécifié), je ne suis pas vraiment après ce que les programmes existants puis-je utiliser pour faire cela.

Était-ce utile?

La solution

Le logiciel tableur mon entreprise fait lit un certain nombre de formats de fichiers binaires, ainsi que des fichiers texte.

Nous examinons d'abord les premiers octets pour un nombre magique que nous reconnaître. Si nous ne reconnaissons pas le nombre magique de l'un des types binaires que nous lisons, nous regardons jusqu'aux premiers 2K octets du fichier pour voir si elle semble être un UTF-8 , de le système d'exploitation hôte. Si elle passe aucun de ces tests, nous supposons que ce n'est pas un fichier que nous pouvons traiter et jeter une exception appropriée.

Autres conseils

Vous pouvez utiliser la commande file. Il fait un tas de tests sur le fichier (man file) de décider si elle est binaire ou texte. Vous pouvez regarder / emprunter son code source si vous devez le faire à partir de 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

Vous pouvez déterminer le type MIME du fichier avec

file --mime FILENAME

Le raccourci est file -i sur Linux et file -I (i majuscule) sur macOS (voir commentaires).

Si elle commence par text/, il est texte, sinon binaire. La seule exception sont des applications XML. Vous pouvez correspondre à ceux en recherchant +xml à la fin du type de fichier.

Eh bien, si vous êtes inspectez le fichier entier, voir si tous les caractères est imprimable avec isprint(c). Il est un peu plus compliqué pour Unicode.

Pour distinguer un fichier texte unicode, MSDN offre quelques-unes d'excellents conseils à ce qu'il faut faire .

L'essentiel de c'est d'abord inspecter jusqu'à quatre premiers octets:

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 

Cela vous dira l'encodage. Ensuite, vous voudriez utiliser iswprint(c) pour le reste des caractères dans le fichier texte. Pour UTF-8 et UTF-16, vous devez analyser les données manuellement depuis un seul caractère peut être représenté par un nombre variable d'octets. De plus, si vous êtes vraiment anal, vous aurez envie d'utiliser la variante locale de iswprint si c'est disponible sur votre plate-forme.

Perl a une heuristique décent. Utilisez l'opérateur -B pour tester binaire (et son contraire, -T à tester pour le texte). Voici sa coquille en une ligne à la liste des fichiers texte:

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

(Notez que ces traits de soulignement sans précédent dollar sont corrects (RTFM).)

La plupart des programmes qui tentent de faire la différence utiliser une heuristique, comme l'examen des premiers n octets du fichier et de voir si ces octets tous se qualifier comme « texte » ou non (c.-à-ils tombent tous dans la gamme de charcters ASCII imprimables). Pour distiction plus fin, il y a toujours la commande « file » sur les systèmes de type UNIX.

Son un vieux sujet, mais peut-être quelqu'un trouve cela utile. Si vous devez décider dans un script si quelque chose est un fichier, vous pouvez tout simplement faire comme ceci:

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

Cela obtenir le type de fichier, et avec un grep silencieux, vous pouvez décider si son texte.

Pour lister les noms de fichiers texte dans répertoire courant / subdirs:

$ grep -rIl ''

Binaires:

$ grep -rIL ''

Pour vérifier fichier particulier, modifier légèrement la commande suivante:

$ grep -qI '' FILE

puis, l'état de sortie « 0 » signifierait le fichier est un texte; '1' - binaire. Pourrait vérifier:

$ echo $?

Une simple vérification est si elle a des caractères \0. Les fichiers texte ne les ont pas.

Comme indiqué précédemment * systèmes d'exploitation nix ont cette capacité au sein de la commande de fichier. Cette commande utilise un fichier de configuration qui définit les nombres magiques contenus dans de nombreuses structures de fichiers populaires.

Ce fichier, appelé la magie a été historiquement stocké dans / etc, bien que cela puisse être dans / usr / share sur certaines distributions. Le fichier magique définit des décalages de valeurs connues pour exister dans le fichier et peuvent ensuite examiner ces emplacements pour déterminer le type du fichier.

La structure et la description du fichier magique peut être trouvé en consultant la page de manuel concerné (magic man)

En ce qui concerne une mise en œuvre, bien que se trouvent dans file.c elle-même, mais la partie pertinente de la commande de fichier qui détermine si elle est un texte lisible ou non est le suivant

/* 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 */
    }

Vous pouvez utiliser libmagic qui est une version de la bibliothèque de la ligne de commande Unix file.

Il y a wrapper pour de nombreuses langues:

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top