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?
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:
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:
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
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:
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
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:
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ì:
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 ?
ho utilizzato il codice da voi postato, scrivendolo cosi:
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:
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...
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:
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):
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
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:
Public Sub Form_Open()
Print DesktopMime.FromFile("/percorso/del/file").Type
End