Seite 1 von 2

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

Verfasst: Di, 23.10.2012 18:48
von ejomi
Hallo und guten Abend (ich arbeite mal wieder länger)!

Der Service "com.sun.star.ucb.SimpleFileAccess" stellt die vielversprechende Methode "getContentType" zur Verfügung. Leider liefert diese unter Windows-XP immer nur den gleichen Typ "application/vnd.sun.staroffice.fsys-file"!! Gibt es noch andere Wege, den MIME-Typ von (nicht geöffneten) Dateien zu ermitteln??

Ich möchte alle MIME-Typen einer Datei-Auflistung haben, die ich vorher mit DIR (bzw. über "getFolderContents" vom oben erwähnten Service) eingelesen habe.

Klar doch: Windows liefert dazu Dateiendungen - ich will aber einen plattform-unabhängigen Code entwerfen!

Grüße aus dem fernen Dresden:
ejomi

(OO: V3.2.1, OS: Win-XP)

Re: Wie MIME-Typen von Dateien ermitteln?

Verfasst: Di, 23.10.2012 19:43
von komma4
SIeh' Dir mal die Funktion GetRealFileContent aus der Library TOOLS an... Stichwort oDocInfo (von mir ungetestet)

Viel Erfolg - und Grüsse aus dem fernen Thailand ;)

Re: Wie MIME-Typen von Dateien ermitteln?

Verfasst: Do, 25.10.2012 09:23
von ejomi
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

Re: Wie MIME-Typen von Dateien ermitteln?

Verfasst: Do, 25.10.2012 09:35
von komma4
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?

Verfasst: Do, 25.10.2012 10:08
von ejomi
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?

Verfasst: Do, 25.10.2012 11:52
von komma4
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?

Verfasst: Do, 25.10.2012 12:25
von DPunch
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?

Verfasst: Do, 25.10.2012 12:34
von Karolus
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?

Verfasst: Do, 25.10.2012 13:40
von balu
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?

Verfasst: Do, 25.10.2012 14:50
von Karolus
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?

Verfasst: Do, 25.10.2012 15:43
von ejomi
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?

Verfasst: Do, 25.10.2012 16:01
von Karolus
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?

Verfasst: Do, 25.10.2012 16:55
von ejomi
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?

Verfasst: Do, 25.10.2012 17:51
von Karolus
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?

Verfasst: Fr, 26.10.2012 11:22
von ejomi
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