Gambas-it

Gambas3 => Programmazione => Topic aperto da: Lux - 08 Marzo 2012, 20:51:16

Titolo: Identificare un tipo di file
Inserito da: Lux - 08 Marzo 2012, 20:51:16
Come faccio ad identificare una tipologia di file? Ad esempio, se ho 3 file, uno video, uno audio ed una immagine, come faccio a far capire al programma qual'è quello video tra i 3? Tramite le estensioni?
Titolo: Re: Identificare un tipo di file
Inserito da: vuott - 08 Marzo 2012, 21:21:55
Come faccio ad identificare una tipologia di file? Ad esempio, se ho 3 file, uno video, uno audio ed una immagine, come faccio a far capire al programma qual'è quello video tra i 3? Tramite le estensioni?

Codice: gambas [Seleziona]

Public Sub button1_Click()

 dim est As String

  est = File.Ext("percorso_del_file")

  Print est

End



Più in particolare per quanto hai chiesto. Supponiamo che hai tre file: uno .avi, uno .wav ed uno .tif:

Codice: gambas [Seleziona]

Public Sub button1_Click()
 Dim ogniFile As String

 For Each ogniFile In Dir("/percorso_cartella_contenente_i_tre_file/", "*.*")

  If File.Ext(ogniFile) = "avi" Then
   Print ogniFile
  Endif
 
 Next

End



...anzi, ancor più brevemente:
Codice: gambas [Seleziona]

Public Sub button1_Click()
 Dim ogniFile As String

 For Each ogniFile In Dir("/percorso_cartella_contenente_i_tre_file/", "*.avi")

' vedo in console quali file .avi sono stati trovati:
    Print ogniFile
  
 Next

End
Titolo: Re: Identificare un tipo di file
Inserito da: sotema - 08 Marzo 2012, 22:12:53
Attento che l'estensionsene può essere ingannevole; ad esempio un file .ogg può essere audio e/o video.
Potrebbe essere una soluzione usare la funzione shell unitamente al comando bash file. Qualcosa del tipo:

Codice: gambas [Seleziona]
Dim sFile As String

  Shell "file " & User.home &/ "Music" &/ "Josh.ogg" To sFile


la stringa sFile conterrà la descrizione del tipo di file, ad esempio nel caso:

/home/emynadia/Music/Josh.ogg: Ogg data, Vorbis audio, stereo, 44100 Hz, ~100000 bps, ...

oppure:

/home/emynadia/Videos/Fast.ogg: Ogg data, Theora video

o ancora:

/home/emynadia/Pictures/gambas.svg: SVG Scalable Vector Graphics image
Titolo: Re: Identificare un tipo di file
Inserito da: vuott - 09 Marzo 2012, 03:37:54
Attento che l'estensionsene può essere ingannevole; ad esempio un file .ogg può essere audio e/o video.
Potrebbe essere una soluzione usare la funzione shell unitamente al comando bash file. Qualcosa del tipo:

Codice: gambas [Seleziona]
Dim sFile As String

  Shell "file " & User.home &/ "Music" &/ "Josh.ogg" To sFile


la stringa sFile conterrà la descrizione del tipo di file

Se il fine del programma è di "far distinguere direttamente dal programma", (come mi pare  :-\ chiedeva Lux), un preciso "tipo" di file fra diversi con la medesima estensione, entrambe le soluzioni da noi proposte, seppur interessanti, non bastano.

Sia riguardo alla tua soluzione che alla mia, pertanto, a mio modesto parere, Lux dovrà far effettuare dal programma comunque un'analisi capace di individuare il tipo di file voluto:
- nella tua soluzione ritengo analizzando le righe presenti nella variabile stringa restituita da Shell, rintracciando uno o due di elementi che identifichino il tipo di file;

- nel mio caso potrebbe farsi un'analisi esadecimale (o anche solo testuale, laddove utile) dell'header (che distingue il tipo di file), oppure di altro segmento del file. Riguardo all'header, ad esempio, per il Midi (...deformazione "professionale"  ;D ) è: 4D 58 68 64  (testualmente è: MThd). Insomma si potrebbe fare una cosa come il seguente esempio:
In una cartella poniamo un vero file Midi e vari file di altro tipo, ai quali cambiamo  :devil: l'estensione in .mid. In questo modo tutti i file, presenti nella cartella, avranno l'estensione .mid ; ma... quale è il vero file Midi ?  :rolleyes:
Allora... risolvo  così:

Codice: gambas [Seleziona]

Public Sub Button1_Click()

 Dim $F, ogniFile As String

  For Each ogniFile In Dir("/percorso_del_file/", "*.mid")

' vedo in console il nome di ciascun file .mid esistente nella cartella:
    Print ogniFile

' quindi me lo carico....
    $f = File.Load("/percorso_del_file/" & ogniFile)

'...e verifico che i primi 4 byte del file caricato corrispondano ai caratteri: MThd
' ossia all'inizio dell'Header Chunk che tipicizza il file Midi standard:
    If Left($f, 4) = "MThd" Then
      Print "Il file Midi VERO è: "; ogniFile
    Endif

  Next

End

...ed infatti funziona.  

...che ne pensi ?
Titolo: Re: Identificare un tipo di file
Inserito da: sotema - 09 Marzo 2012, 09:38:43
e se il file audio/video fosse in formato mp3?
se ricordo bene ma mp3 non ha un vero e proprio header, ma solo dei frame header.
Titolo: Re: Identificare un tipo di file
Inserito da: vuott - 09 Marzo 2012, 14:07:47
e se il file audio/video fosse in formato mp3?
se ricordo bene ma mp3 non ha un vero e proprio header, ma solo dei frame header.

Sì, è vero. ...ma con quale forza miracolosa lo stesso comando "File", da te segnalato, riesce a capire che si tratta di un file .mp3, indicandone addirittura anche alcune caratteristiche essenziali, e non di un video... porno  :P ? E come fa, per esempio, A-Mule/E-Mule a riconoscere i file falsi (fake) ?
Suppongo ci sia qualche parte del codice binario comune a tutti (e solo a loro) i file .mp3 da poter sottoporre e quindi rilevare mediante analisi sintattica (Parsing) !
....
http://stackoverflow.com/questions/4177922/how-to-determine-file-type (http://stackoverflow.com/questions/4177922/how-to-determine-file-type)
http://www.visual-basic.it/articoli/sfTagMP3_ID3_04.htm (http://www.visual-basic.it/articoli/sfTagMP3_ID3_04.htm)
http://www.visual-basic.it/articoli/sfMp3pa5.htm (http://www.visual-basic.it/articoli/sfMp3pa5.htm)
http://pugnonelvento.blogspot.com/2011/11/ricercare-file-audio.html (http://pugnonelvento.blogspot.com/2011/11/ricercare-file-audio.html)
http://forum.html.it/forum/showthread/t-955606.html (http://forum.html.it/forum/showthread/t-955606.html)
http://willcode4beer.com/parsing.jsp?set=mp3ID3 (http://willcode4beer.com/parsing.jsp?set=mp3ID3)
http://www.mp3-tech.org/ (http://www.mp3-tech.org/)
http://www.id3.org/Home (http://www.id3.org/Home)
https://forums.oracle.com/forums/thread.jspa?threadID=2150253 (https://forums.oracle.com/forums/thread.jspa?threadID=2150253)

 ;)
Titolo: Re: Identificare un tipo di file
Inserito da: sotema - 09 Marzo 2012, 15:44:37
in quanto al video porno...è comunque un video!  ;D
Ad ogni modo è vero che anche il comando file ha dei limiti, ad esempio non tratta i file con caratteri speciali, come capita spesso con Amule/Emule.
Titolo: Re: Identificare un tipo di file
Inserito da: vuott - 09 Marzo 2012, 15:50:40
in quanto al video porno...è comunque un video!  ;D

ᶘ(^_^)ᶅ
  /‿ ‿\
     。
 (  ▼  )

Comunque sia, questa discussione ci ha consentito di approfondire un po' l'argomento.... del riconoscimento dei file, intendo !  ;D
Titolo: Re: Identificare un tipo di file
Inserito da: md9327 - 09 Marzo 2012, 16:19:57
Fai una ricerca su "MIME" e/o "MIMETYPE"...
Titolo: Re: Identificare un tipo di file
Inserito da: vuott - 09 Marzo 2012, 16:31:43
Fai una ricerca su "MIME" e/o "MIMETYPE"...
Interessante, ma...... suppongo che il suggerimento sia indirizzato - ovviamente - a Lux ! :P
Titolo: Re: Identificare un tipo di file
Inserito da: Lux - 10 Marzo 2012, 12:46:35
Eccomi tornato, perdonate la mia lunga assenza, ma il lavoro chiama. Mamma mia quanto avete scritto!
Allora comincerò a fare un po di ricerche utilizzando i vostri link, in modo da chiarirmi le idee.
Grazie! :2birre:
Titolo: Re: Identificare un tipo di file
Inserito da: vuott - 10 Marzo 2012, 17:07:47
Allora comincerò a fare un po di ricerche utilizzando i vostri link, in modo da chiarirmi le idee.

Facci sapere eventuali informazioni e soluzioni trovate, nonché progressi con il codice !
Titolo: Re: Identificare un tipo di file
Inserito da: md9327 - 12 Marzo 2012, 16:37:09
E soprattutto fai un bella donazione alla fondazione MD9327!!!  ;D
Titolo: Re: Identificare un tipo di file
Inserito da: vuott - 12 Marzo 2012, 17:07:34
E soprattutto fai un bella donazione alla fondazione MD9327!!!  ;D

Aaaaah ! Ora ho capito il tuo nome !

Make Donation 9327 (euro to my foundation) !

...messaggio subliminare !  


Titolo: Re: Identificare un tipo di file
Inserito da: Lux - 12 Marzo 2012, 21:48:47
Mamma mia, 9327 Euro?  :o comincia a diventare costoso questo forum...... :hatecomputer:
Titolo: Re: Identificare un tipo di file
Inserito da: Lux - 12 Marzo 2012, 22:10:20
ho utilizzato il codice da voi postato, scrivendolo cosi:
Codice: [Seleziona]
Public Sub Main()
  Dim firma, nomifile, stringa As String
  For Each nomifile In Dir(User.Home & "/test")
    Print nomifile
    stringa = File.Load(User.Home & "/test/" & nomifile)
    Print Left$(stringa, 4)
  Next
End
Poi gli ho detto di leggere una cartella con un file png, uno mp3, uno avi ed una wma
mi da questo come risultato:
Codice: [Seleziona]
Schermata del 2012-02-14 13:17:27.png
�PNG
07 - Ligabue - Certe Notti.mp3
ID3^C
ED_1024.avi
RIFF
02 Snow ((Hey Oh)).wma
0&�u
Mi da dei caratteri che non legge, forse sono dei caratteri speciali, magari gambads ha la possibilità di impostare l'utf-8 o come si chiama?
Su internet, ho visto che quello di leggere l'header di un file è forse l'unico modo per identificare un file, anche uno con estensione sbagliata o privo.
Avevo pensato quindi di stampare l'header dei file in modo, da conoscere l'header di ogni tipo di file e quindi associarlo come audio, video, immagine ecc...
Titolo: Re: Identificare un tipo di file
Inserito da: vuott - 12 Marzo 2012, 23:30:54
Mi da dei caratteri che non legge, forse sono dei caratteri speciali,....

Prendiamo come esempio l'header del file .png:
facendo un'analisi esadecimale del file, vediamo che i primi 4 byte sono: 89 50 4E 47.
Il valore non "leggibile in stampa" è il primo: 89, che in decimale = 137. ...in vero, puoi vederlo nel suo "carattere" corrispondente, se vuoi, in questa maniera:

Codice: gambas [Seleziona]

 Print String.Chr(&0089)

e vedrai comparire questo carattere:  ...ma ai tuoi fini quel valore in quanto "carattere", preso cioè come carattere testuale (...quel tipo strano di carattere), non t'aiuta.

Del resto io ritengo che la cosa non ti debba preoccupare, poiché non tutti i file riportano nel proprio header la denominazione della propria estensione. Il file .png sì, ma per esempio il file Midi no; così anche l'.mp3 non riporta i caratteri "mp3" nell'header. Ciò vuol dire che non potrai "estrapolare" l'estensione da lì da convertirla poi in stringa per mostrarla... per esempio in console.

C'è da capire se gli header di tutti i tipi di file, che ci interessano, si trovano tutti ai primissimi byte di ciascun file.
A mio modesto parere, dovresti fare un elenco dei byte identificativi di ciascun tipo di file. Conoscendo i byte ricorrenti (quindi universali) in un determinato tipo di file, potresti effettuare una "selezione" (e quindi il "riconoscimento", l'"identificazione") del tipo di file tramite una corrispondenza fra byte "raccolti" nel file da analizzare, e elenco presente nel programma.

...una cosa di 'sto genere (la butto di getto):

Codice: gambas [Seleziona]

Public Sub Main()

  Dim firma, nomifile, stringa, stringafinale As String
  Dim a As Integer

  For Each nomifile In Dir(User.Home & "/test")
    Print nomifile
    stringa = File.Load(User.Home & "/test/" & nomifile)

' verifico - per esempio - i primi 4 byte/carattere. Sono costretto - ahimé - a 'sto ciclo,
' per poter mutare ogni singolo carattere nel corrispondente codice ASCII:
        For a = 1 To 4
          stringafinale = stringafinale & Asc(Mid(stringa, a, 1))
        Next

'...e li comparo con il mio seguente "elenco" presente nel programma:        
       Select case stringafinale
         Case "137807871"
            Print "Il file " & nomifile & " è di tipo PNG !"
         Case "........ "
            Print "Il file " & nomifile & " è di tipo ..... !"
          Case etc etc
      Select End

        stringafinale = Null
  Next

End

Titolo: Re: Identificare un tipo di file
Inserito da: fsurfing - 13 Marzo 2012, 23:05:19
vi chiedo scusa se non ho letto tutta la discussione, quindi magari già avete affrontato ciò che volevo proporvi...

avete provato con  il comando bash  "file  nomefile" che in base al magic number  descrive il tipo di file?
Titolo: Re: Identificare un tipo di file
Inserito da: vuott - 14 Marzo 2012, 00:53:49
vi chiedo scusa se non ho letto tutta la discussione, quindi magari già avete affrontato ciò che volevo proporvi...
avete provato con  il comando bash  "file  nomefile" che in base al magic number  descrive il tipo di file?

Sì. E' stato proposto da sotema:
http://www.gambas-it.org/smf/index.php?topic=2043.msg22532#msg22532

da lì è nato un dibattito al riguardo.
Titolo: Re: Identificare un tipo di file
Inserito da: vuott - 14 Gennaio 2014, 22:29:06
Fai una ricerca su "MIME" e/o "MIMETYPE"...

Riprendo questo suggerimento di md9327, per segnalare che con le funzioni di Gambas è possibile individuare il mimetype di un file, e quindi la sua tipologia in modo inquivocabile, attivando il componente gb.desktop ed utilizzando, dunque, la sua Classe "DesktopMime" in questo modo:
Codice: gambas [Seleziona]

Public Sub Form_Open()

   Print DesktopMime.FromFile("/percorso/del/file").Type

End