Autore Topic: Comando OPEN - Aprire un file (Read e Write) in modalità RANDOM  (Letto 9682 volte)

Offline Top Fuel

  • Gran Maestro dei Gamberi
  • *****
  • Post: 959
    • Mostra profilo
Re: Comando OPEN - Aprire un file (Read e Write) in modalità RANDOM
« Risposta #30 il: 19 Febbraio 2015, 18:09:21 »
Citazione
1- Non è obbligatorio che tutti i campi debbano essere riempiti, si può anche lasciarli vuoti.
Ma non sei stato tu a parlare di un modo per poter scrivere cose più lunghe senza dover intervenire su quanto scritto dopo?

Si, ma non ho detto che devi metterci dentro obbligatoriamente qualcosa...  :)
Citazione
2- Per eliminare un singolo record non c'è bisogno di riscrivere tutto il file, basta spostare di una posizione indietro tutti i record seguenti.
Magari mi si spiegasse come fare!  :rolleyes:

1- Ti posizioni con Seek sul record successivo a quello da cancellare
2- Leggi il record
3- Ti posizioni con Seek sul record da cancellare
4- Scrivi il record
5- Fai così con tutti quelli successivi
6- Marchi l'ultimo come vuoto
E' più difficile a dirsi che a farsi, basta un ciclo For Next. :)
Citazione
Per il resto direi un buon lavoro. :)
Grazie lo stesso, anche se è una pietosa bugia  :-*

No, l'impegno c'era, ma può essere fatto in maniera più semplice. ;)
Citazione
Intendi dire che se si utilizzasse una struttura si potrebbe usare lo split limitatamente alle due stringhe in quanto poi età e booleano occuperebbero un solo byte ciascuno?
Sarebbe una cosa del genere:

Codice: gambas [Seleziona]
Public Struct mioRecord
sNome as String ' 19 + 1 (tab) con supporto di una funzione.
sCognome as String '   Idem
byEta as Byte '  1 byte
bSposi as Boolean '  1 byte
End Struct

Per un totale di 42 byte invece di 46? Ma si può usare split nelle strutture? A me i tipi creati dall'utente sono sempre apparsi inutili (evidentemente non li capisco proprio).
Poi ci si sposta sempre con Seek di 42 in 42?
Nelle strutture ogni campo occupa la lunghezza della variabile che la rappresenta, quindi, a parte le stringhe e i variant, le variabili numeriche occupano 1, 2, 4 o 8 byte.
Nelle strutture non c'è bisogno di nessuno split, basta usare i campi:
TextBox1.Text = mioRecord.sNome
TextBox2.Text = mioRecord.sCognome
TextBox3.Text = mioRecord.bEta
TextBox4.Text = mioRecord.bSposi
Più semplice di così... :)
« Ultima modifica: 19 Febbraio 2015, 18:11:12 da Top Fuel »
Dear youtube administrators, your search bar is broken. When I type the letter "J" it appears justin bieber when it should appear Jimi Hendrix. Fix this, please.

Offline vuott

  • Moderatore globale
  • Senatore Gambero
  • *****
  • Post: 11.721
  • Ne mors quidem nos iunget
    • Mostra profilo
Re: Comando OPEN - Aprire un file (Read e Write) in modalità RANDOM
« Risposta #31 il: 19 Febbraio 2015, 19:35:10 »
cosa intendi parlando di 8 byte? Le stringhe (al di sotto delle 127 lettere) non occupano un byte ogni carattere?


La lunghezza dipende da molti fattori, tra i quali il formato del codice macchina della CPU destinazione.


Se scriviamo:

Codice: gambas [Seleziona]
     dim s as string = "UNA-STRINGA-LUNGA"
     print s & s


consuma MENO memoria di

    
Codice: gambas [Seleziona]
print "UNA-STRINGA-LUNGA" & "UNA-STRINGA-LUNGA"


Se il compilatore NON capisce che nella print ci sono due costanti letterali uguali, nel codice (o altrove) dovrà inserire le due costanti, separatamente. Ognuna occupa almeno 18 bytes (17 per i dati, +1 almeno, o 4 o 8 a seconda della CPU, per la lunghezza).

Nel frammento precedente, invece, la stringa è specificata una volta sola; poi, ogni volta che la si usa, bastano 8 byte (un Puntatore) in un sistema a 64bit per dire dov'è la stringa e usarla.

Ma tieni presente che "print s & s" PRIMA concatena la stringa (quindi arriviamo a 42 bytes), poi la stampa. Quindi a un certo momento abbiamo bisogno di 42+18 bytes nel primo frammento, e 42+18+18 nel secondo frammento.

Una stringa di ad esempio di 80 caratteri ha bisogno di almeno 81 caratteri, che possono diventare 84, 88, 92 o giù da lì per questioni tecniche. Il numero "5" invece può occupare 1 byte se lo dichiari come byte, oppure 2 oppure 4 oppure 8 oppure 10 - dipende dal contesto.
Sicuramente un puntatore o una variabile tengono meno posto di una stringa di 80 caratteri, ecco quello che volevo dire.

 :rolleyes:

Comunque sia, prova questo:
Codice: gambas [Seleziona]
Public Sub Main()

  Print SizeOf(gb.String)

End
« Ultima modifica: 19 Febbraio 2015, 20:09:42 da vuott »
« Chiunque, non ricorrendo lo stato di necessità, nel proprio progetto Gambas fa uso delle istruzioni Shell o Exec, è punito con la sanzione pecuniaria da euro 20,00 a euro 60,00. »

Offline Gianluigi

  • Moderatore globale
  • Senatore Gambero
  • *****
  • Post: 4.239
  • Tonno verde
    • Mostra profilo
Re: Comando OPEN - Aprire un file (Read e Write) in modalità RANDOM
« Risposta #32 il: 19 Febbraio 2015, 20:28:54 »
@Top Fuel
Prima di risponderti voglio fare un po di prove col codice.
Una cosa però l'anticipo: Ma tutta questa discussione non era nata dal fatto che non essendoci in Gambas le stringhe a lunghezza fissa vi era un problema? E ora concludi con un “Più semplice di così...”

@Vuott
Si mi da 8, ma credevo si riferisse allo spazio di dimensione dato (inizialmente) al momento della dichiarazione.
Quindi Seek non tiene conto dei byte, ma allora cosa misura e perché si sposta precisamente con il mio codice, vuoi dire che sul tuo computer non funziona? Tiene conto (misura) il numero di caratteri?
Se dovessi usare una struttura? Come uso Seek come faccio a dimensionarlo e a spostarmi con esso? :rolleyes:

 :ciao:
nuoto in attesa del bacio di una principessa che mi trasformi in un gambero azzurro

Offline vuott

  • Moderatore globale
  • Senatore Gambero
  • *****
  • Post: 11.721
  • Ne mors quidem nos iunget
    • Mostra profilo
Re: Comando OPEN - Aprire un file (Read e Write) in modalità RANDOM
« Risposta #33 il: 19 Febbraio 2015, 20:30:30 »
Nelle strutture ogni campo occupa la lunghezza della variabile che la rappresenta, quindi, a parte le stringhe e i variant, le variabili numeriche occupano 1, 2, 4 o 8 byte.
Nelle strutture non c'è bisogno di nessuno split, basta usare i campi:
....
Più semplice di così... :)

Uhmmm.... non è poi così tanto semplice. Ed infatti, proprio per questo, io non ho sollecitato un uso delle Strutture.
VB usa sostanzialmente delle Strutture, ma poi ha "dietro le quinte" senz'altro una procedura per gestirle al meglio in fase di scrittura e soprattuto di lettura da un file.

In vero, la scrittura in un file dei dati presenti in una Struttura può vedere una procedura un po' complessa, scrivendo i dati membro per membro (un po' come ha fatto sopra Top Fuel):
Codice: gambas [Seleziona]
Write #hFile,  variabileStruttura.sNome
Write #hFile,  variabileStruttura.sCognome
etc...


oppure può vedere un'unica, breve, sintentica istruzione:
Codice: gambas [Seleziona]
Write #hFile, variabileStruttura As miaStruttura


Ma il processo della lettura dei dati dal file con successivo riempimento dei membri della Struttura, prevederà necessariamente l'uso della funzione Seek per riempirli uno ad uno.

...in vero si potrebbe ottenere una lettura più breve con riempimento in un'unica soluzione della Struttura, ma è procedura delicatissima, dovendosi prestare grande attenzione per gli eventuali necessari "allineamenti" dei dati all'interno dell'area di memoria riservata dalla Struttura medesima !
« Ultima modifica: 19 Febbraio 2015, 20:49:39 da vuott »
« Chiunque, non ricorrendo lo stato di necessità, nel proprio progetto Gambas fa uso delle istruzioni Shell o Exec, è punito con la sanzione pecuniaria da euro 20,00 a euro 60,00. »

Offline Gianluigi

  • Moderatore globale
  • Senatore Gambero
  • *****
  • Post: 4.239
  • Tonno verde
    • Mostra profilo
Re: Comando OPEN - Aprire un file (Read e Write) in modalità RANDOM
« Risposta #34 il: 19 Febbraio 2015, 20:42:59 »
@Vuott
Ci siamo praticamente accavallati con le risposte pertanto attendo un tuo commento prima di rispondere al tuo ultimo post. Vedo però che le mie perplessità sulle strutture non sono campate in aria.
 :ciao:
nuoto in attesa del bacio di una principessa che mi trasformi in un gambero azzurro

Offline vuott

  • Moderatore globale
  • Senatore Gambero
  • *****
  • Post: 11.721
  • Ne mors quidem nos iunget
    • Mostra profilo
Re: Comando OPEN - Aprire un file (Read e Write) in modalità RANDOM
« Risposta #35 il: 19 Febbraio 2015, 20:48:07 »
Quindi Seek non tiene conto...
Se dovessi usare una struttura? Come uso Seek come faccio a dimensionarlo e a spostarmi con esso?


La funzione Seek agisce all'interno di un flusso di dati rappresentati dalla variabile di tipo File oppure Stream, non all'interno di una Stringa di caratteri.
Con la Struttura quella funzione va usata.... come si usa normalmente.   ;D

Esempio.
Poniamo il caso di avere un file lungo 32 byte. All'interno vogliamo scriverci i dati di una Struttura.
In particolare vogliamo che i dati del 3° membro della nostra Struttura siano scritti non sequenzialmente rispetto ai due mebri che lo precedono, bensì al 17° byte (indice 16):
Codice: gambas [Seleziona]
Public Struct STRUTTURA
  b a Byte
  s As Short
  i As Integer
End Struct

Public Sub Main()

  Dim st As New STRUTTURA
  Dim fl As File
  
    With st
      .b = 9
      .s = 999
      .i = 99999
    End With

    fl = Open "/percorso/del/file" For Write
    
    Write #fl, st.b As Byte
    Write #fl, st.s As Short

' Scriviamo i dati dell'Intero a cominciare dal byte di indice 16 del file:
    Seek #fl, 16
    Write #fl, st.i As Integer
    
    fl.Close

End
« Ultima modifica: 19 Febbraio 2015, 20:52:49 da vuott »
« Chiunque, non ricorrendo lo stato di necessità, nel proprio progetto Gambas fa uso delle istruzioni Shell o Exec, è punito con la sanzione pecuniaria da euro 20,00 a euro 60,00. »

Offline vuott

  • Moderatore globale
  • Senatore Gambero
  • *****
  • Post: 11.721
  • Ne mors quidem nos iunget
    • Mostra profilo
Re: Comando OPEN - Aprire un file (Read e Write) in modalità RANDOM
« Risposta #36 il: 19 Febbraio 2015, 20:55:11 »
Vedo però che le mie perplessità sulle strutture non sono campate in aria.

Mah... se usi membro per membro, problemi non ne vedo.
La Struttura è utile come il Vettore, ma quando non hai dati di tipo omogeneo.
« Chiunque, non ricorrendo lo stato di necessità, nel proprio progetto Gambas fa uso delle istruzioni Shell o Exec, è punito con la sanzione pecuniaria da euro 20,00 a euro 60,00. »

Offline Gianluigi

  • Moderatore globale
  • Senatore Gambero
  • *****
  • Post: 4.239
  • Tonno verde
    • Mostra profilo
Re: Comando OPEN - Aprire un file (Read e Write) in modalità RANDOM
« Risposta #37 il: 19 Febbraio 2015, 21:10:11 »
@Vuott
Hai mica provato la mia applicazione?
Se si, ti funziona bene? Il seek si sposta correttamente?
Io non intendevo dire che il seek si sposta nelle stringhe, volevo capire come si deve misurarne lo spostamento, io credevo si misurasse in byte, ma poi mi hai detto che sbagliavo a misurare e allora... :rolleyes:

PS: Ho anche messo il calcolo all'inizio...
nuoto in attesa del bacio di una principessa che mi trasformi in un gambero azzurro

Offline Top Fuel

  • Gran Maestro dei Gamberi
  • *****
  • Post: 959
    • Mostra profilo
Re: Comando OPEN - Aprire un file (Read e Write) in modalità RANDOM
« Risposta #38 il: 19 Febbraio 2015, 21:31:33 »
@Top Fuel
Prima di risponderti voglio fare un po di prove col codice.
Una cosa però l'anticipo: Ma tutta questa discussione non era nata dal fatto che non essendoci in Gambas le stringhe a lunghezza fissa vi era un problema? E ora concludi con un “Più semplice di così...”

Il "più semplice di così" riguarda solo l'assegnazione ai TextBox del contenuto della struttura, non il problema in generale. Lo so benissimo che siccome Gambas non contempla l'accesso random ai file bisogna arrangiarsi in qualche maniera.
Dear youtube administrators, your search bar is broken. When I type the letter "J" it appears justin bieber when it should appear Jimi Hendrix. Fix this, please.

Offline vuott

  • Moderatore globale
  • Senatore Gambero
  • *****
  • Post: 11.721
  • Ne mors quidem nos iunget
    • Mostra profilo
Re: Comando OPEN - Aprire un file (Read e Write) in modalità RANDOM
« Risposta #39 il: 19 Febbraio 2015, 23:13:18 »
...volevo capire come si deve misurarne lo spostamento, io credevo si misurasse in byte....

Lo spostamento lo imposti tu su un indice.

Ponendo sempre il caso di un file formato da 32 byte.....
voglio leggere un byte del file e precisamente il 23°:
Codice: gambas [Seleziona]
Dim b As Byte
...
Seek #hFile, 22   ' il 23° byte è ovviamente il byte di numero indice 22 !
Read #hFile, b


Ora invece voglio leggere un Intero, i cui suoi 4 byte - che lo compongono - cominciano ad esempio dal 17° byte:
Codice: gambas [Seleziona]
Dim i As Integer
......
Seek #hFile, 16
Read #hFile, i   ' ...ovviamente, essendo un Intero, verranno letti 4 byte di seguito (l'Integer occupa "comunque" 4 byte di memoria)


Comunque... guarda, in questi casi bisogna fare le prove:    sbagliare, imprecare, riprovare.
« Ultima modifica: 02 Giugno 2016, 15:25:12 da Gianluigi »
« Chiunque, non ricorrendo lo stato di necessità, nel proprio progetto Gambas fa uso delle istruzioni Shell o Exec, è punito con la sanzione pecuniaria da euro 20,00 a euro 60,00. »

Offline Gianluigi

  • Moderatore globale
  • Senatore Gambero
  • *****
  • Post: 4.239
  • Tonno verde
    • Mostra profilo
Re: Comando OPEN - Aprire un file (Read e Write) in modalità RANDOM
« Risposta #40 il: 23 Febbraio 2015, 20:28:34 »
Rispetto a SEEK: A ben guardare nella documentazione online, non si parla apertamente di byte, questo è quanto li riportato:

Definisce la posizione del puntatore dello stream, per la successiva operazione di lettura / scrittura.
Se Position è negativo, allora il puntatore dello stream viene spostato indietro rispetto alla fine del file.
Per spostare il puntatore dello stream dopo la fine del file, è necessario utilizzare la funzione Lof.


Però poi negli esempi c'è questo, come terzo:

Codice: gambas [Seleziona]
' Move 100 bytes before the end of the file
SEEK #hFile, -100


e qui si parla precipuamente di spostamento indietro di 100 byte.

Pertanto ritengo di poter dire che, malgrado quanto qui precedentemente sostenuto da vuott a cui riconosco peraltro un'enorme maggiore conoscenza di programmazione in generale e di Gambas in particolare rispetto a me, lo spostamento in byte operato da SEEK nello stream corrisponde ad un byte per carattere come dimostrava già in parte la piccola applicazione postata in precedenza e come dimostra ancora meglio la nuova (RecordFisso-0.0.1) versione che qui posto e che fa solo uso di stringhe (a lunghezza fissa) e di SEEK (provata su 3 differenti configurazioni hardware).

Per favorire l'eventuale prova anche ai colleghi del forum interessati che non hanno l'ultima versione (3.6.2) stabile ma versioni precedenti la 3.5 ho messo al posto dello SpinBox una scrollbar + textbox che ne simula più o meno il funzionamento e ho rimosso lo Spinner dalla textlabel che informa l'operatore sull'elaborazione dei dati.
Questa versione è la RecordFisso-SSS-0.0.1 (senza spinbox e spinner).

In questo programma ho accolto il suggerimento di Top Fuel circa l'eliminazione dei record che ora il programma sposta in fondo, marca come cancellati e sovrascrive all'atto di nuovi inserimenti.
Questa è solo una piccola dimostrazione alla (vana?) ricerca della comprensione riguardo la scrittura di stream e l'uso di SEEK e non ha altro scopo che quello. Infatti tutto questo spostare e rispostare record nel file è un modo ben poco raccomandabile a chi avesse a cuore l'integrità dei dati.
Per facilitare le prove, il programma ha un metodo di popolamento automatico del file dati che può essere richiamato da Open togliendovi il commento.

Attenzione il metodo è tarato per un file dati da centounomila record se lo volete più piccolo in modo da poterlo poi aprire per controllarne il contenuto basta cambiare la cifra. :)

Una precisazione: Il programma crea una cartella (visibile) col suo stesso nome nella vostra home con all'interno il file dati denominato mioFile.dat.

Questo programmino è ispirato all'esempio che appare sul sito di Windows che tratta di stringhe fisse e metodo RANDOM indicato da vuott in questa stessa discussione.
Non ho usato una struttura perché fin'ora nessuno è riuscito a spiegarmene i reali vantaggi :P

Applicazioni rimosse: vedi ultimo post
 :ciao:
« Ultima modifica: 27 Febbraio 2015, 14:15:45 da Gianluigi »
nuoto in attesa del bacio di una principessa che mi trasformi in un gambero azzurro

Offline vuott

  • Moderatore globale
  • Senatore Gambero
  • *****
  • Post: 11.721
  • Ne mors quidem nos iunget
    • Mostra profilo
Re: Comando OPEN - Aprire un file (Read e Write) in modalità RANDOM
« Risposta #41 il: 23 Febbraio 2015, 22:32:56 »
Rispetto a SEEK: A ben guardare nella documentazione online, non si parla apertamente di byte
...malgrado quanto qui precedentemente sostenuto da vuott ..... lo spostamento in byte operato da SEEK nello stream corrisponde ad un byte per carattere
...non riesco a capire. :rolleyes:
Per byte mi riferisco ad ogni singolo dato presente nel file, nel flusso; ossia al valore composto da 8 bit, che consente 256 configurazioni di bit distinte, e che è memorizzabile in una variabile char del linguaggio C.    :-\
« Chiunque, non ricorrendo lo stato di necessità, nel proprio progetto Gambas fa uso delle istruzioni Shell o Exec, è punito con la sanzione pecuniaria da euro 20,00 a euro 60,00. »

Offline Top Fuel

  • Gran Maestro dei Gamberi
  • *****
  • Post: 959
    • Mostra profilo
Re: Comando OPEN - Aprire un file (Read e Write) in modalità RANDOM
« Risposta #42 il: 23 Febbraio 2015, 22:56:11 »
Per la cronaca, sto lavorando sul programma appena spiegato da Gianluigi e glie lo sto letteralmente stravolgendo, e la cosa si fa interessante. ;) ;)
Appena lo finisco lo posto.
Dear youtube administrators, your search bar is broken. When I type the letter "J" it appears justin bieber when it should appear Jimi Hendrix. Fix this, please.

Offline Gianluigi

  • Moderatore globale
  • Senatore Gambero
  • *****
  • Post: 4.239
  • Tonno verde
    • Mostra profilo
Re: Comando OPEN - Aprire un file (Read e Write) in modalità RANDOM
« Risposta #43 il: 24 Febbraio 2015, 11:05:33 »
Rispetto a SEEK: A ben guardare nella documentazione online, non si parla apertamente di byte
...malgrado quanto qui precedentemente sostenuto da vuott ..... lo spostamento in byte operato da SEEK nello stream corrisponde ad un byte per carattere
...non riesco a capire. :rolleyes:
Per byte mi riferisco ad ogni singolo dato presente nel file, nel flusso; ossia al valore composto da 8 bit, che consente 256 configurazioni di bit distinte, e che è memorizzabile in una variabile char del linguaggio C.    :-\
Bene allora siamo in due a non capire...  :rolleyes:
Però è proprio qua che mi sorge un'altra domanda per lui:
Perché utilizzare esclusivamente variabili di tipo Stringa ?
Se per esempio, come nel suo programma, io devo inserire 10 valori "età", questi naturamente potranno essere rappresentati ciascuno da un solo byte.
Pertanto, si potrebbe utilizzare per ciascun valore dell'età una variabile di tipo Byte, ...la quale occupa 1 byte di memoria.
La sola variabile Stringa invece occupa ben 8 byte !!! 

...
La lunghezza dipende da molti fattori, tra i quali il formato del codice macchina della CPU destinazione.
...
Una stringa di ad esempio di 80 caratteri ha bisogno di almeno 81 caratteri, che possono diventare 84, 88, 92 o giù da lì per questioni tecniche. Il numero "5" invece può occupare 1 byte se lo dichiari come byte, oppure 2 oppure 4 oppure 8 oppure 10 - dipende dal contesto.
Sicuramente un puntatore o una variabile tengono meno posto di una stringa di 80 caratteri, ecco quello che volevo dire.
Comunque sia, prova questo:
Codice: gambas [Seleziona]
Public Sub Main()

  Print SizeOf(gb.String)

End


...
Però poi negli esempi c'è questo, come terzo:

Codice: gambas [Seleziona]
' Move 100 bytes before the end of the file
SEEK #hFile, -100


e qui si parla precipuamente di spostamento indietro di 100 byte.
...

Credevo di essere stato sufficientemente chiaro circa quello che intendevo.
Ma evidentemente non è così e allora provo a metterla così:

Se SEEK si sposta in base ai byte di memoria come sembra da te sostenuto in questa discussione e nei tuoi esempi, ponendo come studio questo codice:
Codice: gambas [Seleziona]

  Dim b As Byte = 123       ' 1 byte
  Dim s As Short = 123      ' 2 byte
  Dim i As Integer = 123    ' 4 byte
  Dim l As Long = 123       ' 8 byte
 
  ' avendo un file che ha memorizzato in sequenza b s i l
  ' sembrerebbe dal tuo ragionamento che SEEK si dovrebbe
  ' spostare in questo modo (tesi che io cerco di confutare).
  Seek #mioFile, 0 ' dovrei essere su b
  Seek #mioFile, 1 ' dovrei essere su s
  Seek #mioFile, 5 ' dovrei essere su i
  Seek #mioFile, 13 ' dovrei essere su l

SEEK in realtà si sposta in base alle cifre e nel caso appena esposto si dovrebbe spostare così:
0, 3, 6, 9 per trovarsi all'inizio delle cifre, almeno credo anche se non ho fatto prove in tal senso essendomi concentrato su quanto qui discusso e cioè Stringhe A Lunghezza Fissa.

 :ciao:

nuoto in attesa del bacio di una principessa che mi trasformi in un gambero azzurro

Offline Gianluigi

  • Moderatore globale
  • Senatore Gambero
  • *****
  • Post: 4.239
  • Tonno verde
    • Mostra profilo
Re: Comando OPEN - Aprire un file (Read e Write) in modalità RANDOM
« Risposta #44 il: 24 Febbraio 2015, 11:13:44 »
Per la cronaca, sto lavorando sul programma appena spiegato da Gianluigi e glie lo sto letteralmente stravolgendo, e la cosa si fa interessante. ;) ;)
Appena lo finisco lo posto.

Certo è che sei un po lungo  ;D
nuoto in attesa del bacio di una principessa che mi trasformi in un gambero azzurro