Newsgroup: it.comp.lang.visual-basic
Titolo: Come posso cancellare Record in file Random?

Salve, il codice riportato sotto mi permette di "cancellare" i dati nel
file... Ma non cancella i Record, infatti con l'istruzione put #2..., non
faccio altro che ricoprire i record contenenti dei dati con dei record che
non ne contengono.
    k = 0
    Open App.Path & "\dati.dat" For Random As #1 Len = Len(LunRec)
    Open App.Path & "\dati.tmp" For Random As #2 Len = Len(LunRec)
    Do
        Get #1, , LunRec
        If k <> Form2.List1.ListIndex Then
            Put #2, , LunRec
        End If
        k = k + 1
    Loop Until EOF(1)
    Close #2
    Close #1
    Kill App.Path & "\dati.dat"
    Name App.Path & "\dati.tmp" As App.Path & "\dati.dat"
Qualcuno mi sa dire come posso fare per eliminare questi benedetti record
vuoti?! :)
Grazie per l'interessamento e (spero!) per la risposta.
By Gail


[cut]
il problema nel tuo codice è che nella stessa posizione di lettura del file,
scrivi anche sul file secondario.
Per ovviare devi inserire un contatore dei record validi
dim  recordvalidi as integer ' questo conta i recor 'veri'
che incrementi quando il record va scritto
 k = 0
    Open App.Path & "\dati.dat" For Random As #1 Len = Len(LunRec)
    Open App.Path & "\dati.tmp" For Random As #2 Len = Len(LunRec)
    Do
        Get #1, , LunRec
        If k <> Form2.List1.ListIndex Then
---------> recordvalidi = recordvalidi + 1
e che poi utilizzi come puntatore al put
            Put #2, recordvalidi, LunRec
        End If
        k = k + 1
    Loop Until EOF(1)
    Close #2
    Close #1
    Kill App.Path & "\dati.dat"
    Name App.Path & "\dati.tmp" As App.Path & "\dati.dat"
et voilà.
Buon lavoro.

 non ne contengono.
Beh, nemmeno con i database c'è la certezza di ricoprire spazi _logicamente_
vuoti, in genere (salvo, ammettendo ottimizzazioni del motore, in casi
particolari) si "ccoda" sempre, semplicemente segnando cone "logicamente
annullati" alcuni records. Per ottenere un'effettiva riduzione di spazio
(recupero dei records logicamente annullati, ma di fatto presenti) occorre
ricostruire il file su di un altro sul quale trasferire solo i records
"vivi". Per analogia "compattazione" dei database.
Nel tuo caso (il codice mi sembra, a occhio, corretto) scrivi
"sequenzialmente" i records validi nel file .tmp (canale 2), ma non ci dici
se hai fisicamente cancellato il file (nel caso di già esistente) prima di
aprirlo. Se lo stesso esiste già con lunghezza pari a 100 records, anche se
tu lo "ricopri" recuperando e scrivendo solo 2 records, la sua lunghezza
resta invariata. Inoltre, cosa accade se il suo terzo record è segnato come
"vivo"?
Prova con:
    If Dir(App.Path & "\dati.tmp")<>"" then Kill App.Path & "\dati.tmp"


"vivi".
Ok, questo va bene, ma potresti essere cosě gentile da postarmi un esempio
in codice?
Quello che ho postato io in precedenza non elimina effettivamente i record
si limita a ricoprirli con dei record vuoti.
Grazie per il tuo interessamento e le tue risposte.
Ciao.

     Name App.Path & "\dati.tmp" As App.Path & "\dati.dat"
Ti ringrazio, per la risposta, ma non sono riuscito ad eliminare
effettivamente i record...
Comunque credo di aver messo il contetore (k)
Ho provato anche inserendo le correzioni che hai effettuato al mio codice,
ma non ho ottenuto risultati.
I record che voglio "cancellare" vengono ricoperti da record vuoti.
Se hai qualche altra soluzione che mi può aiutare...
Grazie.

 si limita a ricoprirli con dei record vuoti.
Ma hai letto fino in fondo?

> Ma hai letto fino in fondo?
Si, è ho provato in questo modo:
    k = 0
    Open App.Path & "\dati.dat" For Random As #1 Len = Len(LunRec)
------->  If Dir(App.Path & "\dati.tmp")<>"" then Kill App.Path &
"\dati.tmp"
               Open App.Path & "\dati.tmp" For Random As #2 Len =
Len(LunRec)
    Do
        Get #1, , LunRec
        If k <> Form2.List1.ListIndex Then
            Put #2, , LunRec
        End If
        k = k + 1
    Loop Until EOF(1)
    Close #2
    Close #1
    Kill App.Path & "\dati.dat"
    Name App.Path & "\dati.tmp" As App.Path & "\dati.dat"
Ma non funziona, anche perchè credo che comunque non ci sia in precedenza un
file *.tmp visto che lo rinomino!
Oppure sto sbagliando qualcosa... sapresti per favore aiutarmi?
Ti ringrazio.
Ciao

 Oppure sto sbagliando qualcosa... sapresti per favore aiutarmi?
Volentieri, ma occorre capire.
Ho provato il tuo codice, simulando un Type qualsiasi per LunRec e, senza
usare il ListBox, scrivendo solo i records dispari, con qualche
aggiustamento per l'EOF. Funziona perfettamente, ovvero il file che viene
creato contiene _solo_ i records aggiunti (Put #2...) ed è lungo n *
len(lunrec), con n pare al numero dei records fisicamente scritti sul canale
2.
Ora, per favore, pubblica l'intero e reale codice (insomma, quello che serve
per capire), anche la definizione di LunRec. Inoltre, spiega meglio che
cosa, secondo te, non va. Ho la sensazione che si stia equivocando.

 ha scritto nel messaggio
news:ap47h3$fbd$1...@lacerta.tiscalinet.it...

Quello che Lupo cercava di spiegarti è che per eliminare un record in un
file random bisogna ricostruire un file che contenga SOLO i record validi e
rinominarlo poi col nome giusto.
per esempio:
data una struttura come segue:
    private type PROVA
    ID AS INTEGER
    NOME AS STRING * 20
    ERASED AS BOOLEAN
    end type
    dim pro as prova
    dim totrecord as integer
    dim recordbuoni as integer
Ora voglio eliminare fisicamente tutti i record 'nulli'
Naturalmente devo aver previsto in fase di creazione della struttura che un
certo record potesse essere annullato ( nell'esempio ERASED viene posto a
VERO se il record viene cancellato)
Partendo da questa premessa per cancellare tutti i record nulli del file
devo
aprire il file originale
    open Name App.Path &"\prova.dat" for random as #5 len = len(pro)
ricavare il numero totale dei record
    totrecord=lof(5)/len(pro)
aprire un file ospite nuovo ( e deve essere vuoto altrimenti alla fine ci
trovo i record vecchi)
    If Dir(App.Path & "\prova2.dat")<>"" then Kill App.Path &"\prova2.dat"
    open Name App.Path &"\prova2.dat" for random as #6 len = len(pro)
iniziare un loop
    for i = 1 to t
leggere l'ennesimo record
    get#5,i,pro
confrontare il valore di erased
    if pro.erased = false then
il record è 'buono'
    recordbuoni = recordbuoni +1
allora lo scrivo nel nuovo file
    put#6,recorbuoni,pro
fine confronto
    end if
fine loop
    next i
chiudo i files
    close#5
    close#6
Adesso mi ritrovo con 2 files ( quello vero < prova.dat > e quello con i
record 'giusti' < prova2.dat >
Allora uccido prova.dat
    kill "prova.dat"
e ti lascio qui......... ma il file prova2.dat va rinominato ( acc. buco di
memoria )
Ciao

 rinominarlo poi col nome giusto.
Vero, ma aggiungo anche (come ho detto, ho provato) che un contatore non è
necessario.
La sintassi "Put #canale, , dati" indica infatti che scriverà dove si trova
posizionato, la prima volta (se il file è appena stato aperto) all'inizio
del file, la seconda dal/sul secondo record e così via. In tal senso non è
necessario (se la scrittura è sequenziale come nel caso specifico) scrivere
"Put #canale, numero_record, dati". Deve andare, credo che ci sia qualcosa
di oscuro che non è stato specificato o, addirittura, quel che fa non è quel
che si vuole.

 By Gail
Ciao
Andrea