Newsgroup: it.comp.lang.visual-basic
Titolo: [Aito su file binario 2]PF,mi corregete il sorgente ?

da cambiare con = ABC STRINGACAMBIATA"
come suggerito da Ugo Mangini ho cercato su msdn trovando alcune cosette, oltre
a qesto, girando in rete ho trovato un piccolo sorgente di esempio che potrebbe
fare al caso mio.
Bene ho sfoltito il sorgente da alcune cosucce a me non necessarie ed ho
provato.Funziona benino ma, con file oltre ii 1/4 di Mb si inchioda.
Avete la cortesia di corregermi il sorgente (o suggerire una soluzione per la
correzzione) ?.
PS.
Come è evidente non sono esperto in VB ma...
Segue codice:
Private Sub cmdReplace_Click()
    On Error GoTo errhandle
 
    Dim FileNum1 As Integer
    Dim FileNum2 As Integer
    Dim fPos As Integer
    Dim i As Integer
    Dim tFileName As String
    Dim Got As String
    Dim tData As String
    Dim Text2 As String
    Dim Text3 As String
    Dim Text4 As String
    Text2 = "STRINGA_ABC"
    Text3 = "STRINGA_XW3"
    Text4 = "10000" 'buffer
 
    If Len(Text3) < Len(Text2) Then
        For i = 1 To Len(Text2) - Len(Text3)
            Text3 = Text3 & " "
        Next
    End If
    FileNum1 = FreeFile
    FileNum2 = FreeFile + 1
    Got = String(1, " ")
    tFileName = Text1.Text & ".TEMP"
    Open Text1.Text For Binary As #FileNum1
    Open tFileName For Binary As #FileNum2
    Do Until EOF(FileNum1)
        tData = ""
        For i = 1 To Val(Text4)
            Get #FileNum1, , Got
            If EOF(FileNum1) Then Exit For
            tData = tData & Got
        Next
        fPos = InStr(tData, Text2)
        If fPos Then Mid(tData, fPos, Len(Text2)) = Text3
        Put #FileNum2, , tData
    Loop
 
    Close #FileNum1
    Close #FileNum2
    Kill Text1.Text
    FileCopy tFileName, Text1.Text
    Kill tFileName
    y = MsgBox("Cmpletato", vbInformation, "Messaggio
    Exit Sub
errhandle:
    y = MsgBox("Error #" & Err.Number & ", " & Err.Description, vbExclamation,
"Error")
    Exit Sub
End Sub
Grazie
R.Zanni
-- 
Posted from  [193.70.106.130] 
via Mailgate.ORG Server - 
http://www.Mailgate.ORG

 [cut]

una stringa mi sembra contenga al max 64k?
Potrebbe dipendere dal sistema operativo: sugli NT arriva a 2 GB :-)
-- 
ciao, hal

Grazie.proverň


 R.Zanni
Il problema non e' tanto la dimensione in se, quanto il fatto che in realta'
non stai dimensionando un buffer, ma stai leggendo il file un byte per
volta, componendo stringhe da 10000 caratteri in ripetuti cicli for... con
file grossi probabilmente la procedura non si blocca ma e' semplicemente
molto lenta.
Prova con questa... mi sono permesso di fare qualche correzione qua e la e
di rinominare le variabili per renderle un po' piu' "parlanti", in
particolare cerca di non chiamare le variabili stringa 'Text2', 'Text3'
ecc.. in quanto potrebbero creare confusione con i controlli TextBox,
in ogni caso eccola:
Private Sub cmdReplace_Click()
    On Error GoTo errhandle
    Dim FileNum1    As Integer
    Dim FileNum2    As Integer
    Dim strTempFile As String
    Dim strBuffer   As String
    Dim strNewData  As String
    Dim strFind     As String
    Dim strReplace  As String
    strFind = "STRINGA_ABC"
    strReplace = "STRINGA_XW3"
    If Len(strReplace) < Len(strFind) Then
        'rendiamo le 2 stringhe uguali aggiungendo tanti spazi quanta e'
        'la differenza tra quella da cercare e quella da sostituire
        strReplace = strReplace & String(Len(strFind) - Len(strReplace), "
")        End If
    FileNum1 = FreeFile
    FileNum2 = FreeFile + 1
    strTempFile = Text1.Text & ".TEMP"
    Open Text1.Text For Binary As #FileNum1
    Open strTempFile For Binary As #FileNum2
    Do Until EOF(FileNum1)
        'dimensioniamo il buffer e recuperiamo
        'la porzione di file corrispondente
        strBuffer = String(10000, " ")
        Get #FileNum1, , strBuffer
        'ora strBuffer contiene un blocco di 10000 byte,
        'rimpiazziamo tutte le occorrenze della stringa
        'e riscriviamo il blocco nel file temporaneo
        strNewData = Replace(strBuffer, strFind, strReplace)
        Put #FileNum2, , strNewData
    Loop
    Close #FileNum1
    Close #FileNum2
    Kill Text1.Text
    FileCopy strTempFile, Text1.Text
    Kill strTempFile
    MsgBox "Completato", vbInformation, "Messaggio"
    Exit Sub
errhandle:
    MsgBox "Error #" & Err.Number & ", " & Err.Description, vbExclamation,
"Error"
    Exit Sub
End Sub
Ciao
--
Luca Dormio - 
luca....@tin.it
________________________________
"Marty, non stai ragionando in maniera quadridimensionale"
Dr. Emmett L. Brown

Grazie infinite per il tempo speso,proverò con questo sorgente modificato.
R.zanni


Funziona benissimo...grazie mille per l'essenziale aiuto.


         strNewData = Replace(strBuffer, strFind, strReplace)
Ri-AAAARGH ! :-)
e se strReplace c'è, ma è a cavallo fra due strBuffer ?
Meglio usare sempre la Seek, spostandosi ogni volta all'indietro
di una lunghezza superiore a Len(strReplace); è un bel po' più
macchinoso, ma più sicuro.
Un Paperino che c'è già rimasto scottato :-))
Chissà se ora Java dirà: "Papero a scottadito" :-)
E chissà se arriverà a leggere fin quaggiù ? :-)

 macchinoso, ma più sicuro.
Ri-infatti... stesso problema si verificava con la routine originaria,
pero', cosi' a occhio, non vedo come una semplice seek possa evitare o anche
solo limitare la cosa; corri comunque il rischio di spostarti esattamente in
mezzo alla stringa e cominciare la lettura da li, specie se la stringa e'
distribuita in maniera non uniforme, tipo:
XXXXXREPLACEYYYYYREPLACEZZZZZZZZZZZZZZZZZZZZZZREPLACE
pero' probabilmente intendevi qualcosa di piu' elaborato...


 XXXXXREPLACEYYYYYREPLACEZZZZZZZZZZZZZZZZZZZZZZREPLACE
E io _ti_ cito ;-) : "Marty, non stai ragionando in maniera quadridimensionale"
:-P
In effetti non sono stato molto chiaro, cerco di spiegarmi con un esempio.
Immagina una stringa del genere (font fisso, per favore:)
1234567890123replace45678901234replace567890123456789012replace345678901replace2
34567890
In questo caso la stringa da rimpiazzare è di 7 caratteri.
Ipotizza ora un buffer di una qualunque lunghezza: se provi a prendere
un blocco di, poniamo, 35 caratteri, potrebbe capitare che una delle
stringhe da sostituire sia a cavallo dell'inizio e/o della fine del
tuo buffer:
1234567890123replace45678901234repl
Ma, qualunque sia la lunghezza del tuo buffer, se torni indietro di
almeno otto caratteri prima di prendere un certo blocco, sei sicuro
che una stringa di sette caratteri sia sempre interamente compresa
almeno una volta in uno dei tuoi buffer:
1234567890123replace45678901234replace567890123456789012replace345678901replace2
34567890
__________________________________|
                           __________________________________|
__________________________________|
Ovviamente il prog si complica un po'... bisogna oltretutto tener
conto che l'ultimo blocco del file sarà quasi sicuramente più breve
del tuo buffer, e andrà quindi gestito in maniera leggermente diversa.
Ma il tutto si riduce alla gestione di un puntatore.
Spero di essere stato più chiaro... ma ricordo una battuta di
(credo) Ennio Flaiano:
"No, guardi, se lei si spiega con un esempio, io non capisco più niente !"
Bye, G.
P.S.: Mi viene il dubbio che funzioni anche con uno spostamento
_uguale_ alla lunghezza della stringa, ma essere abbondanti è
meglio che essere deficienti... :-)

 __________________________________|
Naturalmente qui OE NON doveva andare a capo e mangiarsi gli spazi... :-|
Vabbe'...
Bye, G.

"No, guardi, se lei si spiega con un esempio, io non capisco più niente !"
roftl
-- 
un hal che deve assicurarsi di non essere visto quando legge i post di Pap ;-)

 In effetti non sono stato molto chiaro, cerco di spiegarmi con un esempio.
[SNIP]
Asesso e' tutto chiaro e assimilato
... e si, dovrebbe funzionare anche con un "rientro" uguale alla stringa
Ciao
--
Luca Dormio - 
luca....@tin.it
________________________________
"Marty, non stai ragionando in maniera quadridimensionale, impara da
Paperino!"
Dr. Emmett L. Brown