Dateierkennung ohne Dateikennung?

Für allgemeine Fragen zur Programmierung mit PureBasic.
Micro
Beiträge: 59
Registriert: 28.12.2006 17:44
Computerausstattung: Intel 10850K, 16GB RAM
div. andere Rechner...
Wohnort: Nordkirchen

Dateierkennung ohne Dateikennung?

Beitrag von Micro »

Moin :)

wie kann man eigendlich herausfinden, um welchen Dateityp es sich handelt?

Bsp:
Anstatt des kompletten Dateinahmen "Bsp vom 03.01.2023.pdf" heißt die Datei "Bsp vom 03.01.2023".
Hier ist die Dateiendung ".pdf" einfach nicht mehr vorhanden, die neue Dateiendung ist also ".2023".

Bei PDF-Dateien würde das ja einfach sein, aber wie würde das JPG-Dateien funktionieren?

Hier mal das, was ich mir überlegt hatte:

Code: Alles auswählen

Global nummer.l = 1
If ExamineDirectory(0, "C:\Temp\", "")  
  While NextDirectoryEntry(0)
    If DirectoryEntryType(0) = #PB_DirectoryEntry_File
      Debug "x - " + DirectoryEntryName(0)
      If ReadFile(0,  DirectoryEntryName(0))
        *MemoryID = AllocateMemory(1000)
        If *MemoryID
          bytes = ReadData(0, *MemoryID, 1000)  ; einlesen 1000 Zeichen der Datei
                                               ; Debug DirectoryEntryName(0) + " --- " + PeekS(*MemoryID, -1, #PB_Ascii)
          If FindString(PeekS(*MemoryID, -1, #PB_Ascii), "%PDF")
            Debug Str(nummer.l) + " PDF - " + DirectoryEntryName(0)
          nummer.l = nummer.l + 1
          EndIf
          
          If FindString(PeekS(*MemoryID, -1, #PB_Ascii), "ÿØÿà")
            Debug Str(nummer.l) + " JPG - " + DirectoryEntryName(0)
          nummer.l = nummer.l + 1
          EndIf
                              
          ; Debug "xxx - " + DirectoryEntryName(0)
          
        EndIf
        
        CloseFile(0)
        FreeMemory(*MemoryID)
      EndIf
    EndIf
  Wend
  FinishDirectory(0)
  Debug "-----------------------"
  
EndIf
Keine Ahnung, ob das der richtige Ansatz ist...

Hab da auch noch eine Frage zu PeekS:
In der Hilfe steht bei der Länge was von einen abschließendes Null-Zeichen. Was ist damit gemeint?

Gruß Frank
PB 5.73 LTS - Win 11 Pro / 64Bit
Benutzeravatar
jacdelad
Beiträge: 404
Registriert: 03.02.2021 13:39
Wohnort: Riesa
Kontaktdaten:

Re: Dateierkennung ohne Dateikennung?

Beitrag von jacdelad »

Bei einem JPEG könntest du prüfen, ob es sich laden lässt. Dann findet aber keine Unterscheidung zwischen JPEG und anderen, unterstützten Bildformaten statt. Wenn es genau JPEG sein soll, dann musst du mal einen Blick in die offizielle Dokumentation werfen, dort findest du auch die magische Zahl.

Außerdem gab es mal so eine DLL, die zig Formate erkennen konnte. War aber nur 32 Bit und ich kann mich weder an den Namen erinnern, noch ob sie noch weiterentwickelt wird (vermutlich nicht). Google könnte dir da helfen.

Zu PeekS: PeekS sucht einen String in einem Speicherbereich. Strings werden in PureBasic immer durch ein 0-Zeichen abgeschlossen (also nicht "0" sondern Chr(0)). Deshalb erwartet PeekS am Ende des zu lesenden Strings eben jenes Chr(0).
Das ist übrigens auch der Grund, weshalb sich Strings nur für die Speicherung von Strings eignen und Verschlüsselungen immer in Speicherbereichen stattfinden sollten (es sei denn, es kommen wieder reine Strings raus).
Guten Morgen, das ist ein schöner Tnetennba!

PureBasic 6.21/Windows 11 x64/Ryzen 7900X/32GB RAM/3 TB SSD
Synology DS1821+/DX517, 130.9TB+50.8TB+2TB SSD
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8809
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken

Re: Dateierkennung ohne Dateikennung?

Beitrag von NicTheQuick »

Schau dir mal das hier an: https://www.ibm.com/docs/en/zos/2.2.0?t ... magic-file
Oder das: http://www.fibel.org/linux/lfo-0.6.0/node76.html
Damit erkennt zum Beispiel Linux um welchen Dateityp es sich handelt. Linux schert sich allgemein nicht um Dateiendungen.
Benutzeravatar
tft
Beiträge: 650
Registriert: 08.09.2004 20:18
Computerausstattung: GFX 3060 Ti , i7 12700F , 32 GB Ram , 900 GB SSD , TV
Wohnort: Dachsen
Kontaktdaten:

Re: Dateierkennung ohne Dateikennung?

Beitrag von tft »

Moin.

Als es noch keine Datei Endungen gab. Wurden meistens die ersten 4 Byte einer Datei zur Erkennung des Datei Type verwendet.
Ich dachte eigentlich das sich das nicht geändert hat. Und der Suffix im Dateiname ist nur zum Komfort eingeführt worden. Um
von aussen zu sehen um was es sich für eine Datei handelt. Wenn ich mich irre ... sorry

Gruss TFT
TFT seid 1989 , Turgut Frank Temucin , CH-Dachsen/DE-Berlin/TR-Antalya
Mein Projekt (Driving School Evergarden)
Codes bei (GitHub) Videos von (YouTube)
Treffen via Discord: Einladung

PB 6.10 | W11 | i7 12700F | 32 GB Ram | RTX 3060 Ti | 60 Herz -TV FullHD
ARDUINO Freak | Sprecher | Game Dev. | Geschichten Erzähler :-)
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8809
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken

Re: Dateierkennung ohne Dateikennung?

Beitrag von NicTheQuick »

tft hat geschrieben: 03.01.2023 09:55 Als es noch keine Datei Endungen gab. Wurden meistens die ersten 4 Byte einer Datei zur Erkennung des Datei Type verwendet.
Ich dachte eigentlich das sich das nicht geändert hat. Und der Suffix im Dateiname ist nur zum Komfort eingeführt worden. Um
Das klappt so immer noch mit vielen Dateitypen, aber lange nicht mehr mit allen. Ich glaube das fängt schon bei MP3s an. Die sind besonders doof konstruiert um sie erkennen zu können und damit bestimmt auch nicht die einzigen.
Axolotl
Beiträge: 274
Registriert: 31.12.2008 16:34

Re: Dateierkennung ohne Dateikennung?

Beitrag von Axolotl »

Das Problem ist ja schon bei einfachen Textdateien gegeben...
Ich habe mal ein Versuch anhand der ersten Bytes einer Datei die Extension zu erkennen gebastelt.
Einfach eine oder mehrere Dateien aus dem Explorer auf das ListiconGadget droppen.
Die Extensions die das Progrämmchen erkennt stehen in der Enumeration....

Code: Alles auswählen

; License   : Free, unrestricted, no warranty whatsoever - Use at your own risk 
;           : Copyright (c) 2023 by A.H. (Axolotl)  
EnableExplicit 

Enumeration EFileExtention  
  #FileExtention_NONE  ; Unknown file extention 
  #FileExtention_BMP   
  #FileExtention_JPEG  
  #FileExtention_PDF   
  #FileExtention_ZIP   
  #FileExtention_7z   
  #FileExtention_WAV  
  #FileExtention_EXE 
EndEnumeration 

Structure TExtension 
  Marker.i  
  Name$ 
  EnumValue.i 
EndStructure 

; --- Constants --------------------------------------------------------------- 

#MARKER_MASK                   = $FFFFFFFF 
#ExtensionTableMaxEntry        = 6  ; set to the number of entries 

Global Dim ExtensionTable.TExtension(#ExtensionTableMaxEntry)  

; -----------------------------------------------------------------------------

Macro SetExtensionTableEntry(_Name_, _Marker_, _Value_) 
  ExtensionTable(Index)\Name$ = _Name_ 
  ExtensionTable(Index)\Marker = _Marker_
  ExtensionTable(Index)\EnumValue = _Value_
EndMacro 

; -----------------------------------------------------------------------------

Procedure InitExtensionTable() 
  Protected Index 
  
  SetExtensionTableEntry("BMP",  $E10364D42,        #FileExtention_BMP)  : Index + 1 
  SetExtensionTableEntry("JPEG", $464A1000E0FFD8FF, #FileExtention_JPEG) : Index + 1 
  SetExtensionTableEntry("PDF",  $362E312D46445025, #FileExtention_PDF)  : Index + 1 
  SetExtensionTableEntry("ZIP",  $2001404034B50,    #FileExtention_ZIP)  : Index + 1 
  SetExtensionTableEntry("7z",   $2001C27AFBC7A37,  #FileExtention_7z)   : Index + 1 
  SetExtensionTableEntry("WAV",  $6EE8446464952,    #FileExtention_WAV)  : Index + 1 
  SetExtensionTableEntry("EXE",  $300905A4D,        #FileExtention_EXE)  : Index + 1 

; ReDim ExtensionTable(Index - 1) 
; Debug "INTERNAL INFO: ReDim Table to " + Str(Index - 1) 
EndProcedure 

InitExtensionTable() 
UndefineMacro SetExtensionTableEntry 

; -----------------------------------------------------------------------------

Procedure.i CheckOnFile(Gadget, FileName$)  ; 
  Protected FILE, marker, index, count 

  FILE = ReadFile(#PB_Any, FileName$) ; read with no flags 
  If FILE 
    marker = ReadInteger(FILE) 
    CloseFile(FILE) 
  EndIf 

  If marker <> 0  ; found something valid 
    Debug "Marker == $" + Hex(marker, #PB_Quad)  ; <= need this for new identified extentions 
    AddGadgetItem(Gadget, -1, FileName$ + #LF$ + #LF$ + "$" + Hex(marker, #PB_Quad)) 

    Count = ArraySize(ExtensionTable()) 
    For index = 0 To Count 
      If (marker & #MARKER_MASK) = (ExtensionTable(index)\Marker & #MARKER_MASK) 
        SetGadgetItemText(Gadget, CountGadgetItems(Gadget)-1, ExtensionTable(index)\Name$, 1) 
        ProcedureReturn ExtensionTable(index)\EnumValue 
      EndIf 
    Next index 
  EndIf 
  ProcedureReturn #FileExtention_NONE 
EndProcedure 

; -----------------------------------------------------------------------------

Procedure main() 
  Protected files$, ii, cnt  

  If OpenWindow(0, 0, 0, 640, 480, "File Extention Detection Example...", #PB_Window_SystemMenu | #PB_Window_ScreenCentered) 
    StickyWindow(0, 1) 
    ListIconGadget(1, 4, 4, 632, 472, "Filename", 432) 
    AddGadgetColumn(1, 1, "Ext", 64) 
    AddGadgetColumn(1, 2, "Marker", 128) 
    EnableGadgetDrop(1, #PB_Drop_Files, #PB_Drag_Copy) 

    Repeat
      Select WaitWindowEvent() 
        Case #PB_Event_CloseWindow
          Break ; say good bye  
     
        Case #PB_Event_GadgetDrop 
          If EventDropType() = #PB_Drop_Files 
            files$ = EventDropFiles() 
            If files$ 
              cnt = CountString(files$, #LF$) + 1 
              For ii = 1 To cnt 
                CheckOnFile(1, StringField(files$, ii, #LF$)) 
              Next ii 
            EndIf 
          EndIf 
      EndSelect
    ForEver 
  EndIf 
  ProcedureReturn 0 
EndProcedure 

End main() 
Using PureBasic latest stable version and current alpha/beta (x64) on Windows 11 Home
Antworten