[gelöst] Wie MIME-Typen von Dateien ermitteln?

Antwort erstellen


BBCode ist eingeschaltet
[img] ist ausgeschaltet
[url] ist eingeschaltet
Smileys sind ausgeschaltet

Die letzten Beiträge des Themas
   

Ansicht erweitern Die letzten Beiträge des Themas: [gelöst] Wie MIME-Typen von Dateien ermitteln?

Re: Wie MIME-Typen von Dateien ermitteln?

von DPunch » Fr, 26.10.2012 18:41

Servus
ejomi hat geschrieben:Dabei bin ich über einen kleinen Programmfehler gestolpert:
Will man die Funktion "GetFileType" mit der Flag "bReturnSignatureIfUnknown" steuern, kommt es zu einem Fehler weil in der betreffenen Bedinung ein nicht existierender Array mit Namen "aTmp" abgerufen wird. Hier muss der Name in "aHexArray" geändert werden, wenn man z.B. bei unbekannten MIME-Typen die HEX-Signatur gezeigt bekommen möchte.
Danke für den Hinweis - ich habe die Angewohnheit, beim ersten Runterschreiben des Codes kurze Benenner wie sTmp, aTmp, nTmp etc. zu verwenden und diese erst am Ende in aussagekräftige Namen zu ändern. Das Array ist mir dabei offensichtlich durch die Lappen gegangen.
Der Ausschnitt ist jetzt auch im ursprünglichen Code angepasst.
ejomi hat geschrieben:Dateien ohne Header (wie z.B. reine Textdateien) lassen sich mit dieser Methode aber grundsätzlich nicht ermitteln.
Das ist ein leider weitverbreitetes Problem (daher auch das ">>Possible<<" in der Signatur-Liste), durch Überprüfung auf Vorhandensein eines ByteOrderMark (BOM) kann man eventuell noch das eine oder andere Textfile identifizieren, aber generell hat man es hier mit einem Thema zu tun, über das sich schon etliche Menschen den Kopf zerbrochen haben. Firefox zum Beispiel verwendet dafür meines Wissens nach eine eigene Heuristik.
Die meisten Lösungen sehen allerdings so aus, dass bei unbekannter Signatur eben die Dateiendung herangezogen wird (genaugenommen machen die meisten Programme dies als erstes). Das zu tun, um zumindest eine gute Vermutung über den MIME-Typ anzustellen, ist ohne großen Aufwand umsetzbar.

Re: [gelöst] Wie MIME-Typen von Dateien ermitteln?

von balu » Fr, 26.10.2012 16:43

Hallo Karo,

ich Danke dir herzlichst für die Links.
Und wenn ich meinen neuen Rechensklaven fäddich habe, dann werd ich mich auch mal mit der Würgeschlange befassen :).


Gruß
balu

Re: Wie MIME-Typen von Dateien ermitteln?

von ejomi » Fr, 26.10.2012 11:22

Danke für die zahlreichen Tipps.

Ich werde nachher den Thread als "gelöst" markieren, weil m.E. zumindest das Prinzip geklärt werden konnte:

1. Die Python-Lösung war für meine Verhältnisse dann doch etwas zu kompliziert: Hier liegt der Teufel im Detail und es stellte sich heraus, dass Python eben doch nicht ganz so einfach ist.

2. Die schnelle Methode mit "GetRealFileContent" aus der Library TOOLS ist ganz passabel, wobei man mit der Einschränkung klar kommen muß, dass eben nur die von OO bekannten Dateitypen zurückgegeben werden.

3. Am praktikabelsten erscheint für mich - als reiner "BASICer" - die Lösung von DPunch, den MIME-Typ über das Auslesen der "Magic number" zu ermitteln, zumal man den Ausgabetext über die Ausgabeliste nach eigenem Bedarf anpassen kann.

Dateien ohne Header (wie z.B. reine Textdateien) lassen sich mit dieser Methode aber grundsätzlich nicht ermitteln.

Dabei bin ich über einen kleinen Programmfehler gestolpert:
Will man die Funktion "GetFileType" mit der Flag "bReturnSignatureIfUnknown" steuern, kommt es zu einem Fehler weil in der betreffenen Bedinung ein nicht existierender Array mit Namen "aTmp" abgerufen wird. Hier muss der Name in "aHexArray" geändert werden, wenn man z.B. bei unbekannten MIME-Typen die HEX-Signatur gezeigt bekommen möchte.

Code: Alles auswählen

   'Empty string means no match found
   If sTranslated = "" Then
      If bReturnSignatureIfUnknown = True Then
          ' E R R O R :  GetFileType = Join(aTmp," ")   ! ! !
          GetFileType = Join(aHexArray," ") 
      Else
         GetFileType = "Unknown signature"
      End If
   Else
      GetFileType = sTranslated      
   End If
Gruß: ejomi

Re: Wie MIME-Typen von Dateien ermitteln?

von Karolus » Do, 25.10.2012 17:51

Hallo
In der 4. Zeile Deiner Funktion "passwort(len)" steht die URL zum Python-Script - habe ich das richtig verstanden?
Ja.
Den Rest davor und danach wird man wohl immer mit kopieren müssen (und - unbedarft wie ich - dabei nur mit den Achseln zucken müssen) - oder?
Mehr oder weniger - Die Funktionsnamen müssen gewechselt werden, und ggf. die Anzahl und die Namen der übergebenen Argumente anpassen.

Falls du Calc-funktionen ohne die leidige Basic-schnittstelle implementieren willst - wirds etwas schwieriger http://www.biochemfusion.com/doc/Calc_addin_howto.html Ein gutes Beispiel dafür ist http://extensions.services.openoffice.o ... numbertext

Karolus

Re: Wie MIME-Typen von Dateien ermitteln?

von ejomi » Do, 25.10.2012 16:55

Karolus hat geschrieben:Hier hab ich noch ein paar Tipps für den Anfang.
Karolus!
Ganz herzlichen Dank dafür! Wirklich gut erklärt: kurz, bündig und man kommt schnell zur Sache.

Hab' auch das Dialog-Fensterchen von Hanya problemlos eingebaut bekommen und Dein Passwort-Dings ebenfalls.
Python scheint ja wirklich einfacher zu sein, als es zunächst aussieht.

Nur der BASIC-Aufruf ist mir noch etwas unheimlich:
In der 4. Zeile Deiner Funktion "passwort(len)" steht die URL zum Python-Script - habe ich das richtig verstanden?

Den Rest davor und danach wird man wohl immer mit kopieren müssen (und - unbedarft wie ich - dabei nur mit den Achseln zucken müssen) - oder?

Gruß: ejomi

Re: Wie MIME-Typen von Dateien ermitteln?

von Karolus » Do, 25.10.2012 16:01

Hallo

OOo/Lo hat halt keine "eingebaute" IDE für Python - aber das ist auch kein großes Problem ( Selbst wenn es etwas Eingebautes, mit der Basic-Ide vergleichbares, gäbe ; würde ich das heute nicht mehr benutzen )
Hier hab ich noch ein paar Tipps für den Anfang.

Karolus

Re: Wie MIME-Typen von Dateien ermitteln?

von ejomi » Do, 25.10.2012 15:43

Hallo und einen schönen Tag,
Karolus hat geschrieben:Python ist hervoragend dokumentiert
... danke für den Link (Englisch ist bei mir nicht so das große Problem) und ich würde mich ja gerne mal etwas tiefer in die Materie einarbeiten, aaaber:

Ich scheitere bereits schon im Ansatz: Öffne ich die OO-Makroverwaltung (Extras/Makros/Makros verwalten/Python..), bleiben alle relevanten Schaltflächen ("Erstellen", "Bearbeiten", usw.) deaktiviert. Hmm - da nutz der beste Wille nichts und die ganze Euphorie ist bereits im Keim erstickt!

Was mache ich falsch??

Gruß: ejomi

Re: Wie MIME-Typen von Dateien ermitteln?

von Karolus » Do, 25.10.2012 14:50

Hallo Balu
Zum Anfangen gibts ein gutes Tutorial http://tutorial.pocoo.org/
Ein deutsches Forumhttp://www.python-forum.de/index.php

Karolus

Re: Wie MIME-Typen von Dateien ermitteln?

von balu » Do, 25.10.2012 13:40

Hallo Karo,
Karolus hat geschrieben: Python ist hervoragend dokumentiert
http://docs.python.org/library/mimetype ... -mimetypes
Könntest Du auch bitte für deutschsprachige Anwender einen empfehlenswerten Link kund tun? Denn ich kann mir gut vorstellen das bei einem Einstieg in eine fremde Programmiersprache in einer fremden Sprache es zu problemen kommt. Und ja, ich spreche da auch von mir. :oops:


Gruß
balu

Re: Wie MIME-Typen von Dateien ermitteln?

von Karolus » Do, 25.10.2012 12:34

Hallo
mal sehen, ob Karolus dazu was zu sagen kann
Was soll ich dazu sagen - Python ist hervoragend dokumentiert
http://docs.python.org/library/mimetype ... -mimetypes

Karolus

Re: Wie MIME-Typen von Dateien ermitteln?

von DPunch » Do, 25.10.2012 12:25

Servus

Es gibt wohl direkt über die API eine Möglichkeit, den MIME auszulesen (OOo Wiki -> Property MediaType), aber mir ist das nicht gelungen.

Stattdessen habe ich auf die Alternative, die über das Auslesen der sogenannten "Magic number", also den Anfangsbytes der Datei, geht, zurückgegriffen:

Code: Alles auswählen

'Defines how far to read from the start of the file, for performance this can be adjusted to the longest known byte signature length
Private Const nBytesToRead as Integer = 22
'Collection that holds the filetypes
Private cHexSignatures

Sub Main
	sURL = "D:\meinBild.JPG"
	MsgBox GetFileType(sURL,True)
End Sub

Function GetFileType(sURL as String, bReturnSignatureIfUnknown as Boolean)
	On Error GoTo ErrorOccured
	If NOT FileExists(sURL)	Then
		GetFileType = "File not found: " & sURL
		Exit Function
	End If
	sURL = ConvertToURL(sURL)	
	oFileAccess = CreateUNOService("com.sun.star.ucb.SimpleFileAccess")
	oInpDataStream = CreateUNOService("com.sun.star.io.DataInputStream")
	Dim aByte() as Byte
	oInpDataStream.setInputStream(oFileAccess.openFileRead(sUrl))	
	oInpDataStream.readBytes(aByte,nBytesToRead)
	nUpper = UBound(aByte)
	If nUpper = -1 Then GoTo ZeroLengthFile
	Dim aHexArray(nUpper) as String
	For i = 0 To nUpper
		nByte = aByte(i)
		'BYTE is signed in Basic so a shift to unsigned is needed
		If nByte < 0 Then nByte = 256 + nByte
		'Add to HexArray with a leading zero if needed
		aHexArray(i) = Right("0" & HEX(nByte),2)
	Next i
	'If not yet done, add known signatures to collection
	If isEmpty(cHexSignatures) Then FillCollection
	sTranslated = GetTranslatedSignature(aHexArray)
	'Empty string means no match found
	If sTranslated = "" Then
		If bReturnSignatureIfUnknown = True Then
			GetFileType = Join(aHexArray," ")
		Else
			GetFileType = "Unknown signature"
		End If
	Else
		GetFileType = sTranslated		
	End If
	On Error Resume Next
	Finally:
	oInpDataStream.closeInput
	Exit Function
	ZeroLengthFile:
	GetFileType = "Zero length file"
	GoTo Finally
	ErrorOccured:
	GetFileType = "An error occured"
	GoTo Finally	
End Function

Function GetTranslatedSignature(ByVal aHexSignature) as String
	On Error Resume Next
	For i = UBound(aHexSignature) To 0 Step -1
		'Check for hits from longest to shortest signature, cut off last entry after each loop
		ReDim Preserve aHexSignature(i)
		s = ""
		s = cHexSignatures.Item(Join(aHexSignature," "))
		If s <> "" Then Exit For
	Next i
	If i >= 0 Then
		GetTranslatedSignature = s
	Else
		GetTranslatedSignature = ""
	End If
End Function

Sub FillCollection
	cHexSignatures = CreateObject("Collection")
	'Add items using .add("Filetype to display","Hex-Signature separated by spaces")
	cHexSignatures.add("PDF","25 50 44 46")
	cHexSignatures.add("JPEG IMAGE","FF D8 FF E0")
	cHexSignatures.add("JPEG IMAGE (EXIF)","FF D8 FF E1")
	cHexSignatures.add("JPEG IMAGE (SPIFF)","FF D8 FF E8")
	cHexSignatures.add("DVD video file","00 00 01 BA")
	cHexSignatures.add("MPEG video file","00 00 01 B3")
	cHexSignatures.add("Windows Media Video/Audio","30 26 B2 75 8E 66 CF 11")
	cHexSignatures.add("QuickTime movie file","6D 6F 6F 76")	
	cHexSignatures.add("Flash movie file","46 4C 56")	
	cHexSignatures.add("WinRAR compressed archive","52 61 72 21 1A 07 00")
	cHexSignatures.add("MP3 audio file","49 44 33")
	cHexSignatures.add("AVI container file","52 49 46 46")
	cHexSignatures.add("Open Document file","50 4B 03 04 14 00 00 08")
	cHexSignatures.add("OXT file","50 4B 03 04 14 00 00 08 08")	
	cHexSignatures.add("Windows/Dos executable file","4D 5A")	
	cHexSignatures.add(">>Possible<< text (XML,HTML) file","3C")
End Sub
Für die Hex-Signaturen gab es leider anscheinend keine verbindliche Liste, deshalb habe ich nur ein paar ausgewählte Formate eingepflegt.
Bei Bedarf kann die Liste auf Basis von z.B. File Signature Database, Wikipedia: List of file signatures, File signatures table oder eben einfache Google-Suche in der Prozedur "FillCollection" erweitert werden.

Re: Wie MIME-Typen von Dateien ermitteln?

von komma4 » Do, 25.10.2012 11:52

ejomi hat geschrieben:... andere Baustelle! Ich brings nur in BASIC (jedenfalls bei OO). Was gibt's denn da für ein Modul??
Habe es auch nur gegoogelt.... mal sehen, ob Karolus dazu was zu sagen kann 8)

Re: Wie MIME-Typen von Dateien ermitteln?

von ejomi » Do, 25.10.2012 10:08

Hallo komma4.
komma4 hat geschrieben:Das entspricht den OOo-internen FilterNames
Habe gerade mal o.a. Funktion ausprobiert und sage "ja und nein": Die Filternamen sind tatsächlich denen von GetRealFileContent verdächtig ähnlich, aber z.B. ist der Typ "oxt" (oxt_OpenOffice_Extension) bei den Filternamen nicht dabei - kann aber auch sein, dass der spezielle Typ eben nur als Filter nicht zur Verfügung steht aber ansonsten im OO-Code vertreten ist.
komma4 hat geschrieben:Deutet darauf hin, dass mit der o.a. Funktion nur OOo-lesbare Mime-Typen erkannt werden.
... ja, scheint wohl so.
komma4 hat geschrieben:Oder vllt. alles in Python programmieren? Da gibt es auch ein Modul...
... andere Baustelle! Ich brings nur in BASIC (jedenfalls bei OO). Was gibt's denn da für ein Modul??

Gruß: ejomi

Re: Wie MIME-Typen von Dateien ermitteln?

von komma4 » Do, 25.10.2012 09:35

ejomi hat geschrieben:- Für ".odt" (application/vnd.oasis.opendocument.text) liefert GetRealFileContent "writer8",
- für ".csv" (text/comma-separated-values) liefert GetRealFileContent "calc_Text_txt_csv_StarCalc"!

Das entspricht den OOo-internen FilterNames

Deutet darauf hin, dass mit der o.a. Funktion nur OOo-lesbare Mime-Typen erkannt werden.

Oder vllt. alles in Python programmieren? Da gibt es auch ein Modul...

Re: Wie MIME-Typen von Dateien ermitteln?

von ejomi » Do, 25.10.2012 09:23

komma4 hat geschrieben:SIeh' Dir mal die Funktion GetRealFileContent aus der Library TOOLS an...
Hallo komma4,

erst mal: danke für die schnelle Antwort - das funktioniert (halbwegs)!

GetRealFileContent erkennt die meisten Dokument- und Grafik-Formate, allerdings leider keine ausführbaren Dateien (das wäre eigentlich wichtig) wie z.B. ".exe", ".cmd" oder ".dll" und auch keine der verbreiteten Video-Formate wie z.B. "mpg", "flv", "mov" oder "avi".

Auch entspricht die Rückabe nicht den allgemein üblichen MIME-Bezeichnungen (=Medientyp/Subtyp), aber trotzdem ist eine eindeutige Unterscheidung möglich.

Beispiele:
- Für ".odt" (application/vnd.oasis.opendocument.text) liefert GetRealFileContent "writer8",
- für ".csv" (text/comma-separated-values) liefert GetRealFileContent "calc_Text_txt_csv_StarCalc"!

... alles etwas gewöhnungsbedürftig aber es geht.

Gruß aus dem (vergleichsweise nicht so fernen) Dresden
nach dem (doch etwas ferneren) Thailand
von: ejomi

Nach oben