Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Dateityp ermitteln (https://www.delphipraxis.net/80823-dateityp-ermitteln.html)

sexy_betty 15. Nov 2006 21:54


Dateityp ermitteln
 
Ich würde gerne überprüfen, ob es sich bei einer Datei um eine Textdatei handelt oder nicht. Soll aber nicht an die dateiendung gebunden sein, also keine überprüfung, ob es eine *.txt datei ist. es gibt ja auch tausend andere endungen, *.html *.pas *.ini...

also praktisch eine überprüfung, ob es sich um eine ascii-datei handelt.
ich hab bisher leider nichts nützliches gefunden :(

Luckie 15. Nov 2006 22:01

Re: Dateityp ermitteln
 
Das wird auch nicht so einfach sein. Die einzige Möglichkeit, die ich sehe ist, zu prüfen, ob ein Zeichen vorkommt, welches kein ASCII Zeichen ist. Ist das der Fall, ist es zu mindest keine ASCII Textdatei.

3_of_8 15. Nov 2006 22:03

Re: Dateityp ermitteln
 
ä ist kein ASCII-Zeichen, aber kann trotzdem Bestandteil einer Textdatei sein.

#0 ist ein ASCII-Zeichen, aber ist nicht in einer Textdatei zu finden.

Luckie 15. Nov 2006 22:05

Re: Dateityp ermitteln
 
Tja, das ist eben das Problem, dass es auch Textdateien gibt, die auch solche Zeichen enthalten. Muss man eben in die Prüfung mit aufnehmen. Das sollte ja wohl nicht das Problem sein. Das Problem ist eben, dass eine Datei unter Windows kein Magic-Byte haben muss, welches sie identifiziert.

sexy_betty 15. Nov 2006 22:13

Re: Dateityp ermitteln
 
wenn ich eine datei beispielsweise in einem memo anzeigen lasse, dann zeigt er die auch an, wenn es eine mp3 datei ist. dann sind das halt nur ziemlich komische zeichen (wir kennen das ja alle). das will ich eigentlich verhindern. er soll dann sagen: 'datei kann nicht angezeigt werden.' aber dafür brauche ich eben eine unterscheidung. so schwer kann das nicht sein, linux guckt doch auch nie auf die endungen, sondern immer in die datei rein,was das für ein typ ist.

und... wie untersuchen ftp-clients, ob sie dateien im ascii oder binary modus hochladen?

es würde ja reichen, irgendweine procedur zu finden, die nur mit "ordentlichem text" etwas anfangen und ansonsten abstürzt, dann könnte man das in einen try-block schreiben... aber mir ist derartiges nicht bekannt :'(

Luckie 15. Nov 2006 22:30

Re: Dateityp ermitteln
 
Ich habe dir doch gesagt, wie man es machen kann und wo die Probleme liegen. Was ist damit nicht in Ordnung?

Panthrax 15. Nov 2006 23:23

Re: Dateityp ermitteln
 
Hallo.

Als Anregung hier vielleicht noch eine leicht zu implementierende Idee:

Das Typische einer Textdatei ist, dass sie Text enthält. Was also ist Text? Man könnte Text so definieren, dass er vorrangig Buchstaben (und Satzzeichen usw.) enthält. Und "vorrangig" könnte man so definieren, dass ein vorrangiger Teil einen Prozentsatz X des gesamten Inhalts ausmacht, bspw. > 70%.

Nach diesem Verfahren kannst du mehrere Zeichenmengen definieren und ihre die Anteile in der Datei berechnen. Et voilà, du hast deine Grundlage deine Kriterien auf eine Textdatei (besser: textbasierte Datei) anzuwenden.

Verbesserungsansätze könnten sein:
  • Berechnung nur auf Dateiteile anwenden und das als repräsentativ für die gesamte Datei ansehen; z.B. nach 100KB, 10% Dateigröße, 50KB am Anfang (und Mitte) und Ende... aufhören zu berechnen
  • K.O.-Kriterien einführen: Anteil der Zeichenmenge <= 0%; bspw. das Vorkommen von Zeichen < #32
Der Ansatz hat sicher keinen Anspruch auf Vollständigkeit. Du könntest das bis zur Syntaxanalyse ausbauen... :mrgreen: Dann könnstest du zumindest für bekannte Formte sicher sein. Aber ich glaube das führt jetzt doch ein bisschen weit...

Gruß,
Panthrax.

sexy_betty 16. Nov 2006 00:26

Re: Dateityp ermitteln
 
@Luckie
das ist schon in Ordnung, danke.
nur konnte ich nicht glauben, dass es dafür keinen einfacheren weg gibt.
wenn ich zum beispiel eine textdatei mit meinem hexeditor öffne, sagt er auch gleich
"...appears to be a text file.
Do you want to open it as text?"
Hat der dann jedes Zeichen überprüft, ob es ascii ist?
aber ich weiß es nicht, villt hat er es ja.

Eine manuelle überprüfung ist ja auch ganz nett.
nur 1. ist das etwas komplexer, wie ihr schon gesagt habt, sonderzeichen, und dann kommen noch steuerzeichen dazu.
2. wirft mich das wieder in einen bereich, in dem ich mich nicht auskenne. wie lese ich einzelne bytes einer datei ein und gucke, ob das byte dem eines ascii-codes oder steuerzeichens entspricht?

eine andere möglichkeit wäre vielleicht, einfach zu überprüfen ob jedes erste bit eines bytes 0 ist, wenn das bei jedem byte so ist, liegt es doch nahe, dass es ascii-codes sind. da drängt sich mir die frage auf, haben ascii steuerzeichen auch eine null am anfang? und wenn ja, wie lese ich mit delphi das erste bit eines bytes aus?

fragen über fragen... das scheint ja ein größeres problem zu werden, als ich dachte, haltet ihr noch durch? :?

@Panthrax
Der Ansatz ist interessant. Ein bischen stört mich da mein perfektionismus. weil nicht immer jede Textdatei dann auch als Textdatei gewertet werden würde. egal, welche kriterien eingeführt werden, normale texte würden leicht erkannt werden, aber extremfälle nicht. was ist zum beispiel mit ganz kurzen texten oder codeausschnitten?
viel interessanter ist das ko-kriterium. wenn zu viele hässliche kleine schwarze vierecke auf dem bildschirm landen, sagt er "nein".
noch dazu könnte man die dateigröße ins verhältnis setzen mit dem angezeigten text. oft wird bei falschen dateitypen nämlich gar nicht viel angezeigt. ein paar beispiele:
-eine wav-sounddatei: RIFF@¬G
-eine flash-datei: CWS–þ
-eine mp3-datei: ÿûd
-eine exe-datei: MZ
also nur wenige zeichen, meistens unter zehn. wobei ihr euch bei den beispielen noch ein paar kleine schwarze vierecke dazudenken müsst, die wurden leider nicht mitkopiert :(
ich ringe mich halt immer nur ungern zu ergebnissen durch, die nur die halbe wahrheit sind. denn so oder so heißt es dann nicht "das ist eine textdatei" sondern nur "das sieht aus wie eine textdatei". kann es wirklich sein, dass man nicht ordentlich zwischen ascii und binary file unterscheiden kann, wie es jeder ftp-client tut?

wahrscheinlich wird so oder ähnlich meine lösung aussehen, wenn das nicht anders klappt. zum beispiel wirklich die einzelnen bytes untersuchen.

wie liest mann denn nun bytes und deren einzelne bits ein?
ratlosigkeit macht sich breit
gruß

_frank_ 16. Nov 2006 02:24

Re: Dateityp ermitteln
 
Zitat:

Zitat von sexy_betty
eine andere möglichkeit wäre vielleicht, einfach zu überprüfen ob jedes erste bit eines bytes 0 ist, wenn das bei jedem byte so ist, liegt es doch nahe, dass es ascii-codes sind. da drängt sich mir die frage auf, haben ascii steuerzeichen auch eine null am anfang? und wenn ja, wie lese ich mit delphi das erste bit eines bytes aus?

ich gehe mal davon aus das du mit erstes bit das MSB meinst also 2^7...
dann kannst du es so auslesen (bzw. jedes beliebiges durch ändern der 7 ;))

Delphi-Quellcode:
const b=128;//10000000
begin
  if (b and (1 shl 7))>0 then
    showmessage('erstes bit gesetzt');
im ASCII gibt es sonderzeichen wo das MSB 0 ist (<=30d imho), aber bedenke das z.B. tab=9d, zeilenumbruch=13d+10d (cr+lf) also auch < 30d sind.
zum Thema Steuerzeichen: http://de.wikipedia.org/wiki/Steuerzeichen

weiterhin schreibst du von ascii...unter windows gilt normal ansi. d.h. zeichen mit gesetztem MSB sind nicht unbedingt Steuerzeichen (sind hauptsächlich Sprachbedingte Zeichen). und bei Unicode (UTF8/16/...) kannst du dich auch nicht mehr auf eine solche Prüfung (MSB=1) verlassen.

Kurzum würde ich nur eine Prüfung auf #0 machen (allein schon aus Performancegründen). das dieses Steuerzeichen bei binärdaten gerne als trennzeichen verwendet wird. Würde aber den Benutzer entscheiden lassen ob er die Datei (im Textmodus) öffnen will...

Übrigends die kleinen schwarzen vierecke sind (hauptsächlich) solche nicht-Text-zeichen ;)
imho arbeiten FTP-Clienten mit einer whitelist, d.h. es ist im programm definiert, welche Dateiendungen im ASCII-Modus hochgeladen werden und der Rest wird binär hochgeladen (es sei denn, man erzwingt den binär/ascii-modus).

die Datei kannst du per Filestream einlesen und die read(-buffer) methoden nutzen um einzelne bytes/blöcke auszulesen...

HTH Frank

Reinhard Kern 16. Nov 2006 02:55

Re: Dateityp ermitteln
 
Liste der Anhänge anzeigen (Anzahl: 1)
Zitat:

Zitat von sexy_betty
@Luckie
das ist schon in Ordnung, danke.
nur konnte ich nicht glauben, dass es dafür keinen einfacheren weg gibt.
wenn ich zum beispiel eine textdatei mit meinem hexeditor öffne, sagt er auch gleich
"...appears to be a text file.
Do you want to open it as text?"
Hat der dann jedes Zeichen überprüft, ob es ascii ist?
aber ich weiß es nicht, villt hat er es ja.

...
ratlosigkeit macht sich breit
gruß

Hallo,

ich würde umgekehrt vorgehen: lies Zeichen, bis n davon NICHT Text sind. Da genügt wahrscheinlich schon n=2 oder 3.

Dazu nimmst du am besten eine erweiterte ASCII-Tabelle (ich füge eine bei, man findet sowas heute garnicht mehr so leicht) und streichst an, was in einem Text vorkommen kann und was nicht. Also z.B. A - Z ist ok und von den Steuerzeichen CR, LF und HT (TAB); NUL ($00) ist dagegen nicht Bestandteil von Textdateien. Du wirst feststellen, die überwiegende Mehrzahl kann Text sein. Am besten lässt sich das mit einer Menge erledigen, so dass man nachher formulieren kann "if NextChar in TextCharSet".

Ob du die Datei als Strings liest oder als Bytes, ist eigentlich nicht so wichtig, da du ja auf Einzelzeichen eines Strings mit "string1[i]" zugreifen kannst.

Delphi-Quellcode:
var nextbyte : byte;
    nottext : integer;
    textfile : file of byte;
{...} 
nottext := 0;
while not eof (textfile) and (nottext < 3) do
  begin
  read (textfile,nextbyte);
  if nextbyte not in TextCharSet then nottext := nottext + 1;
  end;
if nottext >= 3 then writeln ('Dies ist keine korrekte Textdatei');
Dieser Code ist nicht getestet!

Gruss Reinhard


Alle Zeitangaben in WEZ +1. Es ist jetzt 04:17 Uhr.
Seite 1 von 2  1 2      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz