Connaitre le type d'un fichier texte brut (ansi, utf8, unicode, unicode big endian, rtf)

Soyez le premier à donner votre avis sur cette source.

Snippet vu 42 200 fois - Téléchargée 32 fois


Contenu du snippet

Suite a un probleme d'un membres de Delphi.fr qui ne savais pas comment connaitre le type d'un fichier texte brut,
je me suis donc affairé sur cette fonction simple d'un niveau debutant.

elle permet de reconnaitre les fichiers texte (.txt) au format Ansi (ascii), UTF8, Unicode et Unicode big endian, RTF et egalement Word Document (peut ne pas fonctionner avec tout les fichiers .Doc).

Source / Exemple :


type
  TTxtFileType = (txTxtOrBin,
    txUTF8,
    txUNICODE,
    txUNIBIG,
    txRTF,
    txWORDDOC
  );

  TTxtFileSign = record
     Code : TTxtFileType;
     Sign : LongWord;
     Mask : LongWord;
  end;

const
  TxtSignsCount   = 5;
  TxtSign_UTF8    : TTxtFileSign = (Code: txUTF8;    Sign:$00BFBBEF; Mask: $00FFFFFF);
  TxtSign_UNICODE : TTxtFileSign = (Code: txUNICODE; Sign:$0000FEFF; Mask: $FF00FFFF);
  TxtSign_UNIBIG  : TTxtFileSign = (Code: txUNIBIG;  Sign:$0000FFFE; Mask: $00FFFFFF);
  TxtSign_RTF     : TTxtFileSign = (Code: txRTF;     Sign:$74725C7B; Mask: $FFFFFFFF);
  TxtSign_WORDDOC : TTxtFileSign = (Code: txWORDDOC; Sign:$E011CFD0; Mask: $FFFFFFFF);

var
  TxtFileSigns : array[0..TxtSignsCount-1] of TTxtFileSign = (
    TxtSign_UTF8,
    TxtSign_UNICODE,
    TxtSign_UNIBIG,
    TxtSign_RTF,
    TxtSign_WORDDOC
  );

function TypeOfTextfile(const filename : string) : TTxtFileType;
var
  Flux : TFileStream;
  Sign : LongWord;
  N    : integer;
begin
  Flux := TFileStream.Create(FileName, fmOpenRead);
  try
    Flux.Read(Sign, 4);
  finally
    Flux.Free;
  end;

  result := txTxtOrBin;

  for N := 0 to High(TxtFileSigns) do
  begin
    if (Sign and TxtFileSigns[N].Mask) = TxtFileSigns[N].Sign then
    begin
      result := TxtFileSigns[N].Code;
      break;
    end;
  end;
end;

Conclusion :


Woila, vus la simplicitée de la fonction on pourrait meme ajouter d'autre type de documents
qu'ils soit texte brut ou texte formater (RTF, DOC, PDF ect...).

Notez bien que certain format comme le unicode ont une signature de seulement 2 octets et pas 3 comme les autres.

Il ya egalement un interet a savoir si le fichier est Unicode ou Unicode Big Endian car en unicode les caracteres
ne sont pas codé sur 8bits (Ansi / UTF8) mais sur 16bits.
par exemple, la lettre "a" a pour valeur ordinale x61 en Ansi et UTF8,
sa valeur en Unicode est x6100
et en Unicode Big Endian c'est x0061
et il en est de meme pour tout les caracteres icompris le code de retour chariot (x0D0A) :
Ansi/UTF8 = x0D0A
Unicode = x0D000A00
Unicode BE= x000D000A

Ce qui prouve bien qu'il peut etre utile de connaitre le format d'encodage d'un fichier texte meme brut.

ps : comme a l'habitude, pas de zip avec ce code si court.

A voir également

Ajouter un commentaire Commentaires
marco62118 Messages postés 35 Date d'inscription mercredi 30 janvier 2008 Statut Membre Dernière intervention 25 juin 2015
21 oct. 2011 à 23:46
Bonjour
Je ne suis pas un pratiquant du delphi mais cequi m'intéresse et de comprendre le principe de ctte fonction ?
J'ai aussi ce problème de connaitre le codage de mon fichier avant de pouvoir l'ouvrir et je voudrais pouvoir essayer d'adapter votre code à du Visual Prolog
hoby500 Messages postés 86 Date d'inscription mardi 25 février 2003 Statut Membre Dernière intervention 26 mai 2019
22 mars 2011 à 12:43
Salut
Elle n'est pas mal votre fonction, elle m'a rendu service 3 ans après sa publication.
Seulement je vous reproche de l'avoir un peu compliquer la manière de la programmer.

Voici ma version simplifiée et un peu plus étendue :

type
TTxtFileType = (txTxtOrBin, txUTF8, txUNICODE, txUNIBIG, txRTF, txXLS, txWORD, txPDF, txEXE, txZIP);

Const
STxtFileType : array[TTxtFileType] of string
= ('TEXT', 'UTF8', 'UNICODE', 'UNIBIG','RTF', 'WORD', 'Excel', 'PDF', 'BINAIRE', 'ZIP');

//-------------------------------------------------------------------------------

function GetTypeOfTextfile(const filename : string) : TTxtFileType;
type
TTxtFileSign = record
Sign : LongWord;
Mask : LongWord;
end;

const
TxtFileSigns : array[TTxtFileType] of TTxtFileSign
= (
( Sign: $00000000; Mask: $FFFFFFFF), // txTxtOrBin
( Sign: $00BFBBEF; Mask: $00FFFFFF), // txUTF8
( Sign: $0000FEFF; Mask: $FF00FFFF), // txUNICODE
( Sign: $0000FFFE; Mask: $00FFFFFF), // txUNIBIG
( Sign: $74725C7B; Mask: $FFFFFFFF), // txRTF
( Sign: $E011CFD0; Mask: $FFFFFFFF), // txWORDDOC
( Sign: $E011CFD0; Mask: $FFFFFFFF), // txXLS
( Sign: $46445025; Mask: $FFFFFFFF), // txPDF
( Sign: $00005A4D; Mask: $0000FFFF), // txEXE
( Sign: $04034B50; Mask: $FFFFFFFF) // txZIP
);

var
Flux : TFileStream;
Sign : LongWord;
TxtFileType : TTxtFileType;
begin
result := txTxtOrBin;
try

Flux := TFileStream.Create(FileName, fmOpenRead);
try
Flux.Read(Sign, 4);
finally
Flux.Free;
end;

for TxtFileType := High(tTxtFileType) downto Low(TxtFileType) do
if (Sign and TxtFileSigns[TxtFileType].Mask) = TxtFileSigns[TxtFileType].Sign then
begin
result := TxtFileType;
break;
end;
except
// ShowMessage('pb '+ FileName)
end
end;
chesnetda Messages postés 9 Date d'inscription mercredi 31 mai 2006 Statut Membre Dernière intervention 8 février 2010
8 févr. 2010 à 19:25
Juste pour donner raison à DelphiProg (quand on met le doigt dans l'engrenage, ...), la signature WordDoc est en fait la même pour les document PPT et XLS créés avec Office XP (=version 2003 je crois). En utilisant la routine de f0xi sur un DocX (Office 2007), le "sign" est $04034B50...
Cordialement,
David
jackalunion Messages postés 128 Date d'inscription mercredi 8 janvier 2003 Statut Membre Dernière intervention 14 juillet 2008
25 juin 2008 à 04:04
je comprend maintenant votre logique de programation
PhilLU Messages postés 251 Date d'inscription lundi 9 novembre 2009 Statut Membre Dernière intervention 11 mai 2021
25 juin 2006 à 08:54
Salut,
Je cherche à décoder (lire) une disquette de données écrite pour un OS appelé rmx.
après avoir fait un dump, j'arrive à lire quelque chose, mais la plupart des caractères sont des 'carrés' (des caractères non-reconnu donc!
Est-il possible de les lire avec cette routine, ou faut-il la modifier...
Merci pour votre aide précieuse!!
Phil.

Ci joint extrait du dump:
%»Fó'B%|çî;Ý>Ã*3Ð=gÍûLÝ?ð§mo/uåwq(ÉãÌ衹ò'Eü?å???Ïjh#Ñù|?Ò
Îõ|Cùà$LûK®COÞäg
Ïß?S??¹w4p~iàó~OõÖÃ
Afficher les 7 commentaires

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.