Newsgroup: it.comp.lang.visual-basic
Titolo: Confronto fra due File

Salve a tutti... :-)
Ho la necessità di fare il confronto fra due file, principalmente per
verificare se la masterizzazione di un database, sia stata fatta
correttamente...
Attualmente il DB è poco meno di 1,5 Mb e la soluzione che ho adottato
impiega qualche minuto:
Apro i due file come "Binary"
e li leggo con Get un byte alla volta e confronto i due byte.
Per velocizzare il processo potrei leggere 100K alla volta (mi basta
settare le variabili di lettura su 100K, stando attento verso la fine
in modo da leggere solo i byte restanti e non tutti i 100K)...
C'è per caso un sistema più veloce, magari usando qualche api?
Ringrazio anticipatamente per le risposte :-)
-- 
Daniele Pinna  (leva oops. per rispondere) * ICQ "chiedilo"
* Vota il mio sito nella TOP100 Italiana *
Sito Web 
DAPINNA.COM
: 
http://www.dapinna.com
Il Docfa in Pillole:  
http://www.ildocfainpillole.it

soluzione supergrezza: io lancerei la FC del dos e catturerei l'esito.
"lei" è molto, molto  veloce.
comunque non leggerei byte per byte, ma a pezzoni e poi confronti le
stringhe.

kitesurfz ha scritto:

Si... per ora ho fatto così per verificare la velocità...
Poi leggerò a spezzoni di 100Kbyte o anche più...
Tempo fa avevo fatto una funzione simile con il QuickBasic (tempo fa???
secoli fa!!! :-)) ) e mi ricordo che a seconda della grandezza della
stringa poteva impiegare +/- tempo, quindi avevo trovato un giusto
compromesso...


correttamente...
Potresti fare l'hashing dei due files e confrontarli.
Ottieni una stringa pari all' HASH del file, che confronti con quella
dell'altro.
Io ho fatto una cosa simile usando x-md5.zip
è una dll velocissima e abbastanza semplice da usare
http://shorterlink.com/?XRI1BH
che trovi anche qui
http://student.ing-steen.se/asp/md5/x-md5.zip
--
ciao
  Stefano

 dell'altro.
L'hash non è, comunque, univoco.
Diciamo che la probabilità di avere due hash identici con file diversi 
è bassa, ma ovviamente non nulla (altrimenti avremmo inventato il 
miglior compressore della storia dell'informatica...).
Ciao
Alberto
-- 
A questo punto hanno trovato un muro,
un muro duro, molto molto duro,
che siamo noi.

L'hash non è, comunque, univoco.
E' vero, ma la probabilità di avere due files quasi uguali (stessa dimensione)
con il medesimo hash è veramente bassissima, direi zero, mentre in teoria è
possibile avere due files completamente diversi ma con lo stesso hash.
Non dimenticare che tutto il P2P si basa sull'hash e sulla dimensione per il
riconoscimento dei files.
--
ciao
  Stefano

 Ringrazio anticipatamente per le risposte :-)
Io ti proporrei di leggere per intero i due file e infine confrontarli:
    Dim buffera As String, bufferb As String
    Open fileA For Binary As #1
        buffera = String(LOF(1), " ")
        Get #1, , buffera
    Close #1
 
    Open "c:\tmp.tmp" For Binary As #1
        bufferb = String(LOF(1), " ")
        Get #1, , bufferb
    Close #1
 
    If buffera <> bufferb Then
        MsgBox "file diversi"
    Else
        MsgBox "file uguali"
    End If
io ho provato su un file da 22 mb e il mio pc (1.7ghz) ci mette 3-4
secondi circa.
p.s.: questo non è utile se ti serve anche sapere la posizione dove i file
differiscono. inoltre se sono database, forse prima di iniziare questo
confronto serebbe utile confontarne la lunghezza.
Spero di esserti stato utile.
-- 
questo articolo e` stato inviato via web dal servizio gratuito 
http://www.newsland.it/news
 segnala gli abusi ad 
ab...@newsland.it

Nel suo scritto precedente, SB ha sostenuto :

Non lo dimentico.
Anche perchè mi è già successo di avere download corrotti proprio per 
questo.
Due file di stessa dimensione e stesso hash, ma diversi nel contenuto.
Un cluster di qua e un cluster di là, veniva giù una porcheria.


Un cluster di qua e un cluster di là, veniva giù una porcheria.
Sei il primo che sento dire che gli è capitata una cosa del genere.
Avevo sentito di fakes di files con lo stesso hash e dimensione ma credevo
fossero leggende metropolitane.
Comunque per il confronto dei DB di Daniele credo che il metodo con l'hash sia
sicurissimo e veloce.
--
ciao
  Stefano

 sia sicurissimo e veloce.
Dipende dalla criticità della cosa.
Sulla velocità può essere, anche se comunque il sw deve leggere 
entrambi i file (altrimenti un bit sballato potrebbe sfuggire).
Sulla affidabilità... beh, se si trattasse di una cosa da vita o morte, 
non mi fiderei. Ma se si parla di verificare la masterizzazione 
dell'ultimo film porno, va più che bene.


 compressore della storia dell'informatica...).
Un compressore "one way" così riesco a farlo anch'io :)
Ciao 

 
http://student.ing-steen.se/asp/md5/x-md5.zip
Io ho trovato qualcosa in .OCX
mcFullSecurity 3.00
http://download.excite.it/lista.php?id=1586&p=7
Gli algoritmi sono CRC32, DES, DIAMOND, GZIP, HASH, IDEA, RUBY
La pagina lo indica come Freeware, ma le note all'interno dicono
diversamente


 dell'ultimo film porno, va più che bene.
Be ovviamente non mi stavo preoccupando della masterizzazione
dell'ultimo film porno :-)))
Sto apportando un pò di modifiche al progetto FatturaFast (sperando che
qualcuna poi venga considerata valida è integrata nel progetto comune),
tra le quali la gestione password (con obbligo del cambio pwd ogni sei
mesi, come da Dlg 196/2003) e BackUp dei dati...
Ovviamente se il Backup e la verifica la lascio alla buona volonta
dell'utente... tanto vale non implementarle... :-)
Occorre obbligare l'utente a farlo :-)
Cmq per ora ho risolto con il semplice confronti di stringhe di 10000
caratteri per volta ed è abbastanza veloce con un file da poco meno di
1,5 Mb...


 Spero di esserti stato utile.
Non serve sapere la posizione... solo se i file sono uguali o diversi.
Ovviamente prima di fare il controllo verifica l'esistenza dei file e
poi se sono della stessa lunghezza, quindi controlla "stringa" per "stringa"


non mi fiderei. 
Se si trattasse di una cosa da vita o morte non ci si dovrebbe nemmeno fidare
dei supporti CD-R e CD-RW, almeno stando a quello che scrivono qui:
http://punto-informatico.it/p.asp?i=57166&r=PI
--
ciao
  Stefano

magari però non dipendeva da quello)
Guadagneresti in velocità anche usando le api ReadFile e lstrcmpi 
ti scrivi un esempio veloce (da provare) copiaincollando qua e la:
_________________________
Declare Function ReadFile Lib "kernel32" Alias "ReadFile" (ByVal hFile As Long,
lpBuffer As Any, ByVal nNumberOfBytesToRead As Long, lpNumberOfBytesRead As
Long, lpOverlapped As OVERLAPPED) As Long
Declare Function lstrcmpi Lib "kernel32" Alias "lstrcmpiA" (ByVal lpString1 As
String, ByVal lpString2 As String) As Long
Fil="C:\PIPPO:TXT"
Fl& = FileLen(Fil)
BuffSym = Space(Fl&) ' make room in the buffer Legge una stringa di Fl&
caratteri
hFile = CreateFile(Fil, GENERIC_READ, FILE_SHARE_READ, ByVal CLng(0),
OPEN_EXISTING, FILE_ATTRIBUTE_ARCHIVE, 0)
retval = ReadFile(hFile, ByVal BuffSym, Fl&, numread, ByVal CLng(0))
retval = CloseHandle(hFile)    'CHIUDI IL FILE
Fil="D:\PIPPO:TXT"
Fl& = FileLen(Fil)
BuffSym1 = Space(Fl&) ' make room in the buffer Legge una stringa di Fl&
caratteri
hFile = CreateFile(Fil, GENERIC_READ, FILE_SHARE_READ, ByVal CLng(0),
OPEN_EXISTING, FILE_ATTRIBUTE_ARCHIVE, 0)
retval = ReadFile(hFile, ByVal BuffSym1, Fl&, numread, ByVal CLng(0))
retval = CloseHandle(hFile)    'CHIUDI IL FILE
    If lstrcmp(BuffSym, BuffSym1) = 0 Then
        Me.Print "The strings are the same (case sensitive)"
    End If
_________________________
 
--
ciao
  Stefano

 ha
scritto:
Ho scritto troppo in fretta e ho anche sbagliato API
lstrcmpi è case insensitive e lstrcmp invece è case sensitive, e anche più
veloce a comparare.
_________________________
Declare Function ReadFile Lib "kernel32" Alias "ReadFile" (ByVal hFile As Long,
lpBuffer As Any, ByVal nNumberOfBytesToRead As Long, lpNumberOfBytesRead As
Long, lpOverlapped As OVERLAPPED) As Long
Declare Function lstrcmp Lib "kernel32" Alias "lstrcmpiA" (ByVal lpString1 As
String, ByVal lpString2 As String) As Long
Const GENERIC_READ = &H80000000, GENERIC_WRITE = &H40000000
Const FILE_SHARE_READ = &H1, FILE_SHARE_WRITE = &H2, OPEN_ALWAYS = 4,
FILE_ATTRIBUTE_NORMAL = &H80
Const OPEN_EXISTING = 3, CREATE_ALWAYS = 2
Const FILE_ATTRIBUTE_ARCHIVE = &H20
Dim BuffSym As String, Fil as String
Fil="C:\PIPPO:TXT"
Fl& = FileLen(Fil)
BuffSym = Space(Fl&) ' make room in the buffer Legge una stringa di Fl&
caratteri
hFile = CreateFile(Fil, GENERIC_READ, FILE_SHARE_READ, ByVal CLng(0),
OPEN_EXISTING, FILE_ATTRIBUTE_ARCHIVE, 0)
retval = ReadFile(hFile, ByVal BuffSym, Fl&, numread, ByVal CLng(0))
retval = CloseHandle(hFile)    'CHIUDI IL FILE
Fil="D:\PIPPO:TXT"
Fl& = FileLen(Fil)
BuffSym1 = Space(Fl&) ' make room in the buffer Legge una stringa di Fl&
caratteri
hFile = CreateFile(Fil, GENERIC_READ, FILE_SHARE_READ, ByVal CLng(0),
OPEN_EXISTING, FILE_ATTRIBUTE_ARCHIVE, 0)
retval = ReadFile(hFile, ByVal BuffSym1, Fl&, numread, ByVal CLng(0))
retval = CloseHandle(hFile)    'CHIUDI IL FILE
    If lstrcmp(BuffSym, BuffSym1) = 0 Then
        Me.Print "The strings are the same (case sensitive)"
    End If
BuffSym="":BuffSym1=""
_________________________
 
--
ciao
  Stefano

 
http://punto-informatico.it/p.asp?i=57166&r=PI
Acquistare una unità a nastro non se ne parla nemmeno :-)))
Fino ad ora non ho mai avuto problemi con i CD-R... qualcuno con i CD-RW
formattati con InCD e usati in parte sul mio PC in parte su altri PC
(con versioni diverse di InCD)...
Ovviamente sto escludendo tutti i CD di altre persone usato malissimo,
graffiati sotto o peggio sopra...


 ti scrivi un esempio veloce (da provare) copiaincollando qua e la:
Ti ringrazio :-)
Appena posso lo provo... e ti faccio sapere :-)


 capitare casualmente?
Se un file è lungo 1MB (binario), e un Hash è lungo, che so, 32 
caratteri ASCII, capisci anche tu che la massima lineare indipendenza è 
infinitamente più bassa nell'hash che nel file vero e proprio.
Questo significa che, anche volendo considerare l'hash binario (che non 
è, ed essendo Ascii ha un contenuto informativo ancora minore), il 
rapporto minimo di ripetizione dell'hash è di (1024*1024)/32, ossia 
32768.
Questo significa che immaginando di produrre TUTTE le possibili 
combinazioni di file lunghi 1MB (ossia 1024*1024*256=268mln), avremmo 
blocchi di 32768 file che hanno lo stesso Hash. Certo, rapportato a 
268mln, fa una probabilità di collisione di 1 su 8192, ma non è 
comunque nulla.
Tutto sta nel valutare se si tratti di una probabilità accettabile o 
meno.
E, soprattutto, se per calcolare due hash (che richiedono comunque la 
lettura di entrambi i file per intero) si impieghi meno tempo che per 
fare una comparazione cluster per cluster.


Appena posso lo provo... e ti faccio sapere :-)
Tieni conto che durante la lettura dei files il grosso del lavoro lo fanno i DMA
e quindi il tempo di lettura dipende dall'hardware, e può essere diverso se il
file è già in ram (cash), quindi lanciando due volte successive lo stesso
programma potrseti avere tempi diversi, mentre l'api fa la comparazione di
stringhe in un tempo minore che la corrispondente istruzione VB.
--
ciao
  Stefano

 stringhe in un tempo minore che la corrispondente istruzione VB.
Ok... :-)
