Kommen die zu verarbeitenden Daten aus dem Dateisystem, kann eine Prüfung auf die Dateierweiterung schon einen oberflächlichen Anhaltspunkt liefern. Windows begnügt sich übrigens mit der oberflächlichen Formaterkennung, was durchaus zur Folge haben kann, dass eine Bilddatei als Text deklariert wird, weil die Dateiendung gerade nicht zum Datenformat der Datei passt.
In der Unix Betriebssystemwelt geben sich Programme hingegen ehr selten mit Dateiendungen ab. Die Identifikation des vorliegenden Datenformats findet hier anhand der Magic Bytes - also den ersten vier Bytes der Datei statt. Die ersten vier Bytes eines Jpeg komprimierten Bildes lauten zum Beispiel 0xff 0xd8 0xff 0xe0.
Dateiformaterkennung anhand der Magic Bytes ist für Software immer die erste Wahl, da die Prüfung viel präszierer ist, als die Dateiendung aus dem Filesystem. Spätestens, wenn beim Auslesen nur noch ein InputStream vorliegt, kommt man mit den Dateiendungen nicht weiter. So vermeidet man bereits präventiv, dass Daten auf einen Algorithmus losgelassen werden, für den diese gar nicht geeignet sind.
In der Praxis gibt es bereits fertige Bibliotheken, die sich um die Datenformaterkennung kümmern. Eingesetzt habe ich bereits die Mime Type Detection Utility, die bereits eine vielzahl an gängigen Datenformaten erkennen können.
Vor eine besondere Herausforderung wird eine Datenformaterkennungssoftware bei der Erkennung von Text gestellt. So wird bei UTF Kodierten Texten noch häufig die verwendete Byte-Reihenfolge (Big- oder Little-Endian) in die ersten zwei Bytes kodiert, spätestens bei ASCII ist aber schluß. Die Erkennung von ASCII erfordert also echte Kreativität. Mein erster Ideenansatz ging in Richtung Textanalyse - also zum Beispiel zu prüfen, ob ein Text ein übliches Maß an Leerzeichen enthält, was aber nur eine ungenügende Annäherung ist. Ein Blick in den Source des Mime Type Detection Utility förderte noch einen anderen Ansatz zu Tage. Dieses dreht die These um und prüft, ob es sich bei den gegebenen Daten um Binärdaten handeln könnte. Auch dies ist wiederum nur eine Annäherung, aber durchaus praktikabel. So kann bei erwarteten Textdaten zumindestens geprüft werden, ob es sich bei den gegebenen Daten eben NICHT um Text handelt.
Ohne lange Umschweife, hier der Source aus dem Mime Type Detection Utility dazu:
/** * This is a quick check for the byte array to see if it contains binary data. * * As no known text encoding can have a character containing more than maxNullValues consecutive negative bytes * method does a quick and dirty elimination of what are probably binary files but should never eliminate possible text files. * * It is possible that some binary files will not have maxNullValues consecutive byte * values especially if it's a small file and will slip through here. Later tests should eliminate these. */ public static boolean isBinary(byte[] data) { // No text file should have 2 or more consecutive NULL values final int maxNullValues = 2; int negCount = 0; for(int i = 0; i < data.length; i++) { if(data[i] == 0) { negCount++; } else { negCount = 0; } if(negCount == maxNullValues) { return true; } } return false; }
Keine Kommentare:
Kommentar veröffentlichen
Hinweis: Nur ein Mitglied dieses Blogs kann Kommentare posten.