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 40 902 fois - Téléchargée 30 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

Messages postés
35
Date d'inscription
mercredi 30 janvier 2008
Statut
Membre
Dernière intervention
25 juin 2015

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
Messages postés
86
Date d'inscription
mardi 25 février 2003
Statut
Membre
Dernière intervention
26 mai 2019

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;
Messages postés
9
Date d'inscription
mercredi 31 mai 2006
Statut
Membre
Dernière intervention
8 février 2010

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
Messages postés
129
Date d'inscription
mercredi 8 janvier 2003
Statut
Membre
Dernière intervention
14 juillet 2008

je comprend maintenant votre logique de programation
Messages postés
250
Date d'inscription
lundi 9 novembre 2009
Statut
Membre
Dernière intervention
4 septembre 2020

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.