Gambas-it

Gambas3 => Programmazione => Topic aperto da: Jack_Gamb - 11 Febbraio 2015, 19:46:00

Titolo: Comando OPEN - Aprire un file (Read e Write) in modalità RANDOM
Inserito da: Jack_Gamb - 11 Febbraio 2015, 19:46:00
Salve a tutti.   :)

Vorrei cheidere il vostro aiuto, circa l'uso di un paticolare comando per gestire I/O su files.
Ho cercato se esisteva già un tread sull'argomento ma non l'ho trovato (spero di non aver cercato male).   :-\

Si tratta del comando OPEN.

Quel che mi serve fare è poter aprire un file in scrittura in modo casuale (RANDOM e non sequenziale).

Per quel pochissimo che so, in Visual Basic il modello del comando adatto sarebbe il seguente:

               Open filename For Random Access Read Write As #filenumber Len = reclength

Leggendo (forse non sufficentemente) la documentazione di Gambas, non ho trovato alcun riferimento all'opzione
"random" del metodo di apertura del file con il comendo Open.

Il mio scopo è quello di poter registrare e manutenere l'inventario di un magazzino, all'interno di un semplice file di testo.

Nel file, per ogni articolo (item), sarà presente una riga (record) che conterrà i dati specifici (campi) di quel particolare
oggetto (es: codice, descrizione, quantità, prezzo, ecc).

Le informazioni lette (o quelle da scrivere) sul file saranno poi elaborate dal programma, salvandole negli elementi di un
costrutto (struttura "Type") appositamente definito (in cui ogni elemento è stato dichiarato in modo tale da poter contenere
il tipo di dato di ciascun singolo campo del file di testo).

Dunque:
1) individuare una specifica riga di un file di testo (opportunamente formattato)    (OPEN-READ-RANDOM)
2) caricare tale riga nel costrutto appositamente dichiarato
3) modificare uno o più dei valori delle variabili costutuenti il suddetto TYPE
4) ri-salvare nel file la stessa riga, con i nuovi dati (nella stessa identica posizione, senza generare un duplicato (OPEN-WRITE-RANDOM)

Il mio problema è che in Gambas non riesco a trovare il comando corrispondente a quello che ho scritto sopra e cioè quello
che consente di aprire un file e di poter accedere a qualsiasi sua riga in modo non sequenziale ma CASUALE (e che dunque mi
permetterebbe di ri-salvare facilmente un singolo record dinuovo dentro al file nella stessa posizione, individuandolo in
maniera univoca).

P.S.
come avrete capito non sono un esperto di programmazione ed al contempo desidererei non dover stravolgere il metodo
descritto sopra.
Dunque ovviamente sarò grato a chiunque mi dedicherà un pò del proprio tempo e mi potrà dare un aiuto, ma sarò grato in
maniera maggiore a coloro che non rispondranno a questo tread con informazioni che nulla hanno a che fare con la mia domanda
specifica (es. "... perchè non abbandoni il file di testo e usi un DB", oppure: "... scrivendo tutto ciò in Cobol si potrebbe fare
così ...", oppure "che tipo di processore usi...", ecc).
Questo mi confonderebbe solamente e non risponderebbe al mio quesito.

Spero che qualcuno più competente di me mi sappia aiutare.
Grazie a tutti.    :)
Titolo: Re: Comando OPEN - Aprire un file (Read e Write) in modalità RANDOM
Inserito da: pastrank - 11 Febbraio 2015, 22:34:54
Tu, se non capisco male, sei a parlare di leggere un file usandolo come archivio: penso dovresti usare una struttura a lunghezza fissa, per la velocita', e andare a cercare la posizione su cui scrivere. Vedi un po' se http://www.gambas-it.org/wiki/index.php?title=Seek (http://www.gambas-it.org/wiki/index.php?title=Seek) ti puo' essere utile (intendo l'uso di seek: ovvero, calcoli la posizione dove scrivere, e la' scrivi).
Titolo: Re: Comando OPEN - Aprire un file (Read e Write) in modalità RANDOM
Inserito da: vuott - 11 Febbraio 2015, 23:06:53
Ho cercato se esisteva già un tread sull'argomento ma non l'ho trovato (spero di non aver cercato male).

Ho trovato questa discussione che fa riferimento anche alla parola Random del VB:
http://www.gambas-it.org/smf/index.php?topic=830.0
Titolo: Re: Comando OPEN - Aprire un file (Read e Write) in modalità RANDOM
Inserito da: Top Fuel - 12 Febbraio 2015, 16:31:55
Il problema è che in Gambas non esistono le stringhe a lunghezza fissa, quindi bisogna operare come nella discussione che ha appena segnalato Vuott, riempiendo i caratteri inutilizzati in ogni stringa con caratteri fittizi per portarla ad una lunghezza prestabilita e per leggere/scrivere un determinato record spostarsi con Seek all'interno del file di un numero di posizioni multiplo della lunghezza dei record sommata.
Ecco, una cosa che manca a Gambas e che secondo me poteva essere comoda a quelle che (come me) non sanno niente di SQL e che (sempre come me) non hanno nessuna intenzione di impararlo :) è proprio la modalità random per la gestione degli archivi.
Titolo: Re: Comando OPEN - Aprire un file (Read e Write) in modalità RANDOM
Inserito da: Gianluigi - 12 Febbraio 2015, 18:38:38
Ecco, una cosa che manca a Gambas e che secondo me poteva essere comoda a quelle che (come me) non sanno niente di SQL e che (sempre come me) non hanno nessuna intenzione di impararlo :) ...

Io avevo un compagno di giochi che (forse per fare lo spiritoso) si soffiava il naso con le cose più impensate anche due pietre... La gente è libera di fare ciò che preferisce.
Io ho sempre usato il fazzoletto :P
 :ciao:
PS: SQL è fantastico e SQLite è leggerissimo.
Titolo: Re: Comando OPEN - Aprire un file (Read e Write) in modalità RANDOM
Inserito da: vuott - 12 Febbraio 2015, 20:13:14
Il problema è che in Gambas non esistono le stringhe a lunghezza fissa, quindi bisogna operare ... riempiendo i caratteri inutilizzati in ogni stringa con caratteri fittizi per portarla ad una lunghezza prestabilita e per leggere/scrivere un determinato record spostarsi con Seek all'interno del file ....
Ecco, una cosa che manca a Gambas e che secondo me poteva essere comoda...

Non sono d'accordo con questa opinione di TopFuel per le ragioni che qui espongo.

1) Non bisogna dimenticare che qua si opera sostanzialmente con la memoria.

2) I caratteri fittizi risultano essere utili, a mio avviso, solo quando si devono gestire gruppi di dati la cui dimensione complessiva non è sempre la stessa. Poniamo il caso di dover leggere più "gruppi" significativi di dati da un file, il cui numero all'interno di uno o più gruppi, appunto, può variare di volta in volta.
La domanda che si pone è: dove finisce ogni gruppo di dati che presi in quella quantità ha un sigificato per il programma ?
In tal caso uno stratagemma può essere quello di prevedere l'inserimento, in fase di loro scrittura nel file, di un valore fittizio.

3) Il caso della modalità "Random" in VB.
Questa procedura del modo "Random" del VB mi pare che sia sostanzialmente fondata sull'uso di una specie di Struttura, nella quale va impostata la dimensione di ciascuna stringa di dati, probabilmente riservando una quantità di memoria stabilita dal programmatore, in modo tale che ogni volta verrà letto dal flusso un numero - appunto - "fisso", ben determinato, di dati a cominciare da un preciso byte del flusso.
L'unico automatismo (e quindi l'eventuale comodità) risiede nella circostanza che richiamando un membro di quel tipo personalizzato di variabile (...una specie di Struttura), è VB che sposta (probabilmente servendosi della funzione fseek() di C ) il puntatore interno del flusso al byte stabilito.



- Possibili soluzioni in Gambas -

In Gambas l'assenza di una esplicita funzionlità definita come stringa "a lunghezza fissa" può essere colmata non solo nel modo indicato dall'utente naderit qui per la lettura: http://www.gambas-it.org/smf/index.php?topic=830.msg8981#msg8981

ma anche meglio utilizzando i potenti metodi .Read() e .Write() delle variabili vettoriali.

In entrambi i casi, qualora sia necessario spostarsi in modo arbitrario con il puntatore interno del flusso, si utilizza - come ha già suggerito pastrank - la funzione Seek (...che non è un mostro informatico, giacché esiste analogamente anche in C).
La funzione Seek consente di operare in modo non usuale, arbitrario, rispetto alla modalità normale della consequenzialità dello spostamento del puntatore interno al flusso di dati. Quando noi leggiamo o scriviamo in un flusso di dati (rappresentato da variabili di tipo File o Stream) il puntatore interno si sposta automaticamente in avanti per un numero di byte pari alla quantità di memoria occupata dal tipo di variabile (Byte, Short, Integer, etc) utilizzato in quella lettura o scrittura, ponendosi sul primo byte immediatamente successivo.

Esempio in lettura:
Codice: gambas [Seleziona]
Public Sub Main()

  Dim fl As File
  Dim bb As Byte[]
  
    fl = Open "/percorso/del/file/da/leggere" For Read
    
    With bb = New Byte[Lof(fl)]
      .Read(fl, 0, 9)
    End With
    Print bb.ToString(0, 9)
    
    Seek #fl, 8
    bb.Read(fl, 0, 10)
    Print bb.ToString(0, 10)

    fl.Close

End
Titolo: Re: Comando OPEN - Aprire un file (Read e Write) in modalità RANDOM
Inserito da: Gianluigi - 12 Febbraio 2015, 20:32:17
@vuott
come sempre magistrale

@Top Fuel
se avessi saputo che vuott poi calava il carico tirandoti le orecchie :) non avrei proferito verbo  :-*

 :ciao:
Titolo: Re: Comando OPEN - Aprire un file (Read e Write) in modalità RANDOM
Inserito da: vuott - 13 Febbraio 2015, 10:00:45
In vero, aveva già dato la soluzione l'amico pastrank suggerendo l'uso della funzione Seek (https://gambaswiki.org/wiki/lang/seek?l=it) .
Titolo: Re: Comando OPEN - Aprire un file (Read e Write) in modalità RANDOM
Inserito da: Top Fuel - 13 Febbraio 2015, 14:23:24
3) Il caso della modalità "Random" in VB.
Questa procedura del modo "Random" del VB mi pare che sia sostanzialmente fondata sull'uso di una specie di Struttura, nella quale va impostata la dimensione di ciascuna stringa di dati, probabilmente riservando una quantità di memoria stabilita dal programmatore, in modo tale che ogni volta verrà letto dal flusso un numero - appunto - "fisso", ben determinato, di dati a cominciare da un preciso byte del flusso.
L'unico automatismo (e quindi l'eventuale comodità) risiede nella circostanza che richiamando un membro di quel tipo personalizzato di variabile (...una specie di Struttura), è VB che sposta (probabilmente servendosi della funzione fseek() di C ) il puntatore interno del flusso al byte stabilito.

Nel VB funzionava così: dovevi creare una struttura con le variabili che ti servivano (non solo stringhe, di qualunque tipo) nella quale, a differenza di Gambas, le stringhe dovevano essere a lunghezza fissa, poi creare una variabile da quella struttura che veniva usata come record di lettura/scrittura ed al momento di usare Open, fornire la lunghezza totale della variabile. In questa maniera Seek si posizionava automaticamente all'inizio di ogni record.
In Gambas la mancanza di stringhe di lunghezza fissa complica le cose se si vuole agire sull'archivio un record alla volta, perchè se le stringhe occupano la loro lunghezza effettiva, ogni record ha una lunghezza differente dall'altro.
E poi, se al giorno d'oggi tutti (meno me :) ) usano i database e sql, istruzioni come Open/Read/Write diventano obsolete ed inutili. Come mai allora come mai Minisini si è sbattuto ad implementarle?
Titolo: Re: Comando OPEN - Aprire un file (Read e Write) in modalità RANDOM
Inserito da: Gianluigi - 13 Febbraio 2015, 15:22:15
...
In Gambas la mancanza di stringhe di lunghezza fissa complica le cose se si vuole agire sull'archivio un record alla volta, perchè se le stringhe occupano la loro lunghezza effettiva, ogni record ha una lunghezza differente dall'altro.
...

Vorresti spiegare anche a un niubbo,
stai sostenendo che l'esempio di vuott non funzionerebbe su strutture di tipi di dato diversi fra loro essendo di diverse lunghezze? Giusto?
 :ciao:
Titolo: Re: Comando OPEN - Aprire un file (Read e Write) in modalità RANDOM
Inserito da: Gianluigi - 13 Febbraio 2015, 16:39:45

La funzione Seek consente di operare in modo non usuale, arbitrario, rispetto alla modalità normale della consequenzialità dello spostamento del puntatore interno al flusso di dati. Quando noi leggiamo o scriviamo in un flusso di dati (rappresentato da variabili di tipo File o Stream) il puntatore interno si sposta automaticamente in avanti per un numero di byte pari alla quantità di memoria occupata dal tipo di variabile (Byte, Short, Integer, etc) utilizzato in quella lettura o scrittura, ponendosi sul primo byte immediatamente successivo.


Ma qui vuott sembrerebbe sostenere il contrario...
 :ciao:
Titolo: Re: Comando OPEN - Aprire un file (Read e Write) in modalità RANDOM
Inserito da: Top Fuel - 13 Febbraio 2015, 18:59:41
In Gambas la mancanza di stringhe di lunghezza fissa complica le cose se si vuole agire sull'archivio un record alla volta, perchè se le stringhe occupano la loro lunghezza effettiva, ogni record ha una lunghezza differente dall'altro.

Vorresti spiegare anche a un niubbo,
stai sostenendo che l'esempio di vuott non funzionerebbe su strutture di tipi di dato diversi fra loro essendo di diverse lunghezze? Giusto?
 :ciao:

Rispondendo anche alla domanda successiva, ogni record è memorizzato sul file immediatamente dopo al precedente, secondo la sua lunghezza, ed immediatamente prima del successivo. Ma come la mettiamo se leggiamo un record, ne cambiamo la lunghezza e poi lo riscriviamo sul file? Sopratutto se non è l'ultimo e sopratutto se è diventato più lungo perchè magari abbiamo allungato una stringa aggiungendo delle parole? Quel record andrebbe a sovrascrivere il successivo, a meno che Gambas non vada automaticamente a spostare in avanti i record successivi (dubito) o lo facciamo noi da programma (complicato).
Aspetto la risposta di Vuott. :)
Titolo: Re: Comando OPEN - Aprire un file (Read e Write) in modalità RANDOM
Inserito da: vuott - 13 Febbraio 2015, 20:54:24
Ma come la mettiamo se leggiamo un record, ne cambiamo la lunghezza e poi lo riscriviamo sul file? Sopratutto se non è l'ultimo e sopratutto se è diventato più lungo perchè magari abbiamo allungato una stringa aggiungendo delle parole? Quel record andrebbe a sovrascrivere il successivo, a meno che Gambas non vada automaticamente a spostare in avanti i record successivi (dubito) o lo facciamo noi da programma (complicato).
Aspetto la risposta di Vuott.

     sanmidi
O San Midi (http://it.wikipedia.org/wiki/Musical_Instrument_Digital_Interface), musico ed anacoreta,
   tu che puoi e dai soddisfazione,
   deh, sciogli ogni dubbio, limite d'ogni meta.
   Dammi tu la soluzione:
   io m'affido solo a te,
   io m'affido solo a te !


Rispondo con un esempio pratico.
Poniamo il caso di avere un file di testo, nel quale vi sono i seguenti caratteri:
 abcde123456ABCDE
Tale stringa di testo è costituita da 3 gruppi (record) significativi:
abcde
123456
ABCDE
Decidiamo di aggiungere al secondo gruppo significativo ad esempio i seguenti 3 caratteri: )*+
Come auspicato da TopFuel, l'inserimento/aggiunta dei 3 caratteri non deve coprire quelli del terzo gruppo (record). Inoltre la procedura non deve essere complicata (...che significherà  ??? )
Comunque sia ecco l'esempio:
Codice: gambas [Seleziona]
Public Sub Main()

  Dim fl As File
  Dim bb, cc As Byte[]
 
' Individuiamo i caratteri da aggiungere:
    cc = [41, 42, 43]
 
' Apriamo in lettura ed in scrittura al quale aggiungere i tre byte/caratteri:
    fl = Open "/percorso/del/file" For Read Write
 
' Creiamo ed istanziamo il vettore che accoglierà i dati letti dal file:
    With bb = New Byte[Lof(fl)]
' Leggiamo il file:
      .Read(fl, 0, bb.Count)
' Ecco il metodo che ci consente di inserire agevolmente e con sicurezza uno o più dati nella stringa.
' Gambas sposterà automaticamente in avanti i record successivi (in questo caso l'ultimo):
      .Insert(cc, 11)
' Poiché la lettura dei dati nel file, precedentemente effettuata, ha comportato uno spostamento automatico
' del puntatore di posizione in avanti nel file, lo riposizioniamo all'inizio, per poter riscrivere nel file la nuova stringa di caratteri:
      Seek #fl, 0
      .Write(fl)
   End With

' Chiudiamo il fusso di dati e... accendiamo un cero di ringraziamento a San Midi:   
    fl.Close

End




Se vuoi evitare il Seek ed abbreviare il codice si può fare così:
Codice: gambas [Seleziona]
Public Sub Main()
 
  Dim bb, cc As Byte[]

   cc = [41, 42, 43]

   With bb = Byte[].FromString(File.Load("/percorso/del/file"))
     .Insert(cc, 11)
     File.Save("/percorso/del/file", String@(.data))
   End With

End
Titolo: Re: Comando OPEN - Aprire un file (Read e Write) in modalità RANDOM
Inserito da: Top Fuel - 13 Febbraio 2015, 20:58:47
Ma così devi caricare in memoria TUTTO il file per modificare un solo record. Oltre al fatto che ero capace di farlo anche io :P non mi pare il massimo dell'efficienza, sopratutto se il file è bello grosso.
Con la modalità random del VB caricavi in memoria solo il record da modificare e scrivevi nel file solo il record modificato, senza toccare il resto del file.
Titolo: Re: Comando OPEN - Aprire un file (Read e Write) in modalità RANDOM
Inserito da: vuott - 13 Febbraio 2015, 21:28:36
Ma così devi caricare in memoria TUTTO il file per modificare un solo record. ... non mi pare il massimo dell'efficienza, sopratutto se il file è bello grosso.

Tu mi hai chiesto una risorsa ed una procedura efficace, che producesse gli effetti da te sopra indicati; e la mia soluzione rispetta questo criterio.

Inoltre, il caricamento in memoria di grosse quantità byte non mi pare che oggi giorno sia un problema mortale.
Nei miei esempi, presenti nella WIKI, di esecuzione dei file audio con funzioni esterne in alcuni casi si arriva a caricare in memoria anche diverse decine di milioni di byte !



Con la modalità random del VB caricavi in memoria solo il record da modificare e scrivevi nel file solo il record modificato, senza toccare il resto del file.
......vorrei proprio vedere il codice C che c'è dietro quella risorsa.    ;D
Titolo: Re: Comando OPEN - Aprire un file (Read e Write) in modalità RANDOM
Inserito da: pastrank - 13 Febbraio 2015, 22:23:56
come la mettiamo se leggiamo un record, ne cambiamo la lunghezza e poi lo riscriviamo sul file? Sopratutto se non è l'ultimo e sopratutto se è diventato più lungo perchè magari abbiamo allungato una stringa aggiungendo delle parole?

Se usi record a lunghezza fissa, perche' vuoi metterne uno piu' lungo? Se tieni la lunghezza fissa, puoi permetterti di leggere con metodi tipo

Codice: [Seleziona]
# scritto a memoria, non ho gambas su questo pc
fn = Open nomedelfile For Read
for i = 0 to lof(fn) / lunghezzadelfile -1
Seek #fn, 1000 * i
Read #fn, x, 10
next
Close #fn

e scrivere allo stesso modo: se tieni i record lunghi, non hai problemi con la lunghezza della stringa, la termini con un carattere tipo tab e quando vai a rileggerla tutta la tagli su quello.
Titolo: Re: Comando OPEN - Aprire un file (Read e Write) in modalità RANDOM
Inserito da: vuott - 14 Febbraio 2015, 00:15:04

Se usi record a lunghezza fissa, perche' vuoi metterne uno piu' lungo?

Giustamente l'amico pastrank fa rilevare che nel caso di definizione di un'area di memoria riservata, dunque fissa, con il tipo personalizzato, non ha senso poi ipotizzare una variazione della dimensione di uno o più membri, dunque una dinamicità della lunghezza.

Sono caduto nell'errore io stesso (http://levipere.com/wp-content/plugins/smilies-themer/Axendr/SmileySuicide.gif) scrivendo quel codice per cercare di risolvere il problema.

Pongo nuovamente la riflessione: come agisce VB con la modalità Random ? Certo non per magia ! Quali sono le istruzioni che stanno dietro ?  Qualche procedura comunque adotta...

Ad ogni modo continuo a sostenere la soluzione di pastrank con la funzione Seek.
Titolo: Re: Comando OPEN - Aprire un file (Read e Write) in modalità RANDOM
Inserito da: Top Fuel - 14 Febbraio 2015, 10:24:07
Pongo nuovamente la riflessione: come agisce VB con la modalità Random ? Certo non per magia ! Quali sono le istruzioni che stanno dietro ?  Qualche procedura comunque adotta...

Quali istruzioni ci siano dietro non lo so, devi chiederlo a Guglielmo Cancelli. ;D
Comunque questa modalità esisteva fin dal QuickBasic più di 25 anni fa.
Titolo: Re: Comando OPEN - Aprire un file (Read e Write) in modalità RANDOM
Inserito da: Top Fuel - 14 Febbraio 2015, 10:52:17
come la mettiamo se leggiamo un record, ne cambiamo la lunghezza e poi lo riscriviamo sul file? Sopratutto se non è l'ultimo e sopratutto se è diventato più lungo perchè magari abbiamo allungato una stringa aggiungendo delle parole?
Se usi record a lunghezza fissa, perche' vuoi metterne uno piu' lungo?

No, non è il record ad essere più lungo, è la lunghezza di un componente del record a variare. Usando le strutture di Gambas con le variabili stringa di Gambas, se in una ci scrivo "Vuott", questa occupa 5 byte, se dopo ci scrivo "Pastrank" l'occupazione diventa di 8 byte, se lo scrivo sul file il nuovo record sovrascriverà i prime 3 byte del record successivo, a meno che di spostare avanti di 3 byte tutto il contenuto seguente del file. Con i record a lunghezza fissa del VB questo problema non c'è, perchè se il contenuto della stringa è minore della lunghezza il restante viene riempito con caratteri fittizi, se è invece più lunga l'eccedenza viene troncata.
Titolo: Re: Comando OPEN - Aprire un file (Read e Write) in modalità RANDOM
Inserito da: vuott - 14 Febbraio 2015, 14:46:49
Quali istruzioni ci siano dietro non lo so, devi chiederlo..

...ma forse non mi sono spiegato bene: dietro l'innocente nome di una funzione può esserci una procedura complessissima, non necessariamente meno o molto meno dispendiosa rispetto a quella che puoi scrivere tu.
Può darsi che anche VB si carichi tutto in memoria e poi riscriva il file, oppure prenda una o più parti e per ricomporle adeguatamente con i nuovi dati utilizzi il fseek() .
Insomma la funzione può sembrare offrire il massimo dell'efficienza, ma questo perché non si conosce il suo sviluppo effettivo. A mio modesto avviso, la procedura va considerata non da un punto di vista di codice di alto livello, ma di basso livello.

Se poi tu mi dici: "Sì, va be', però è un lavoro che fa lui e mi evita di perdere tempo a scriverlo io.", ....che ti devo dire ? Il livello del linguaggio si alza sempre di più: fa appunto tutto lui.   :-\



No, non è il record ad essere più lungo, è la lunghezza di un componente del record a variare. Usando le strutture di Gambas con le variabili stringa di Gambas, se in una ci scrivo "Vuott", questa occupa 5 byte, se dopo ci scrivo "Pastrank" l'occupazione diventa di 8 byte, se lo scrivo sul file il nuovo record sovrascriverà i prime 3 byte del record successivo, a meno che di spostare avanti di 3 byte tutto il contenuto seguente del file.
...ma la quantità di memoria utilizzata dai due linguaggi per fare questa procedura mi appare identica.
A me sembra che la differenza stia solo nel momento della scrittura dei nuovi dati nel file:
* VB possiede una funzione che agisce automaticamente in base alla nuova quantità dei dati;
* Gambas possiede una funzione che deve essere impostata dal programmatore: si resta ad un livello può basso.



Con i record a lunghezza fissa del VB questo problema non c'è, perchè se il contenuto della stringa è minore della lunghezza il restante viene riempito con caratteri fittizi, se è invece più lunga l'eccedenza viene troncata.
E' semplicemente un lavoro che fa lui invece di farlo il programmatore.  :-\


Guarda....... non so....  :-\ ho scritto tutte 'ste cose perché io sono un po' contrario alla famosa "pappa pronta" a tutti i costi nella programmazione.
Titolo: Re: Comando OPEN - Aprire un file (Read e Write) in modalità RANDOM
Inserito da: Gianluigi - 16 Febbraio 2015, 11:26:59
Scusate se riprendo la discussione con apparente ritardo ma ero rimasto in attesa di eventuali vostri nuovi post.

Io fin'ora se dovevo memorizzare dei dati in una mia applicazione ricorrevo ad un database.  ;)

Sono pertanto digiuno di quanto qui voi siete a discutere e anticipo le mie scuse per eventuali castronerie.
Se non ho interpretato male quanto sostiene pastrank con record a lunghezza fissa si riferisce non a tutto il file, ma appunto allo spazio dato ad ogni singolo record che poi verrà riempito in parte dai dati veri e propri, parla anche di carattere di fine record.
Quindi se fosse scritto su un file di testo sarebbe come una roba così: Passo a s la stringa da scrivere con tanto di carattere di fine stringa e che poi misuro con Len, sottraggo dal numero di caratteri fissi (es. 20) e aggiungo spazi quanto basta con Space pertanto non dovrei fare spostamenti se al posto di vuott inserisco pastrank basta ridurre il numero di spazi.
Se quanto detto è corretto, teoricamente lo comprendo perché è come l'assegnazione dei numeri di caratteri per le stringhe nei database, non capisco però come sia possibile farlo in pratica con il vostro file.
Parrebbe pertanto esistere un fraintendimento fra pastrank + vuott e Top Fuel.
Urgerebbe esempio pratico.
 :ciao:
Titolo: Re: Comando OPEN - Aprire un file (Read e Write) in modalità RANDOM
Inserito da: vuott - 16 Febbraio 2015, 19:28:47
Urgerebbe esempio pratico.

......
http://support.microsoft.com/kb/150700/it
http://support.microsoft.com/kb/639331/it
Titolo: Re: Comando OPEN - Aprire un file (Read e Write) in modalità RANDOM
Inserito da: Top Fuel - 17 Febbraio 2015, 00:22:18
Non è cambiato niente dai tempi del QuickBasic. :D :D
Titolo: Re: Comando OPEN - Aprire un file (Read e Write) in modalità RANDOM
Inserito da: Gianluigi - 17 Febbraio 2015, 19:13:42
 
Codice: vb [Seleziona]
 Type MyRecord
      LastName as String*20
      FirstName as String*20
      Age as Integer
      Married as Boolean
   End Type
' LastName richiede 20 byte, FirstName richiede 20 byte, età richiede 2 byte e Married richiede 2 byte, in modo che il totale è 20 + 20 + 2 + 2 = 44.


Scusate tutti quanti ma a causa della niubbaggine stento a ben spiegare quello che intendo dire.
Io intendevo più o meno questo (rimanendo in tema VB):
Codice: [Seleziona]
Private $sNome As String    ' 20 = 19 + tab
Private $sCognome As String ' 20 idem
Private $sEta As String     ' 2 + tab
Private $sSposato As String ' 1 + tab

Private $nLungo As Long
Private Const lunghezzadelfile As Byte = 45

Public Sub Form_Open()

  If Exist(User.Home &/ Application.Name &/ "mioFile.dat") Then
    $nLungo = lungo()
    SpinBox1.MaxValue = $nLungo
  Else
    SpinBox1.MaxValue = 1
  Endif
  SpinBox1.MinValue = 1 
  Me.Center 
  
End

'' SCRIVE
Public Sub Button1_Click()
  
  Dim fl As File  
  Dim nomedelfile As String
  
  If TextBox1.text = "" Or TextBox2.Text = "" Or TextBox3.Text = "" Or TextBox4.Text = "" Then
    Message.Info("Impossibile aggiungere record se i dati non sono completi")
    Return
  Endif

  $sNome = fissaScrivo(TextBox1.Text)
  $sCognome = fissaScrivo(TextBox2.Text)
  $sEta = eta(TextBox3.Text)
  $sSposato = sposi(TextBox4.Text)
  
  If Not Exist(User.Home &/ Application.Name &/ "mioFile.dat") Then
    Mkdir User.Home &/ Application.Name
  Endif
  nomedelfile = User.Home &/ Application.Name &/ "mioFile.dat"
  If Not Exist(nomedelfile) Then
    fl = Open nomedelfile For Create
    
  Else
    fl = Open nomedelfile For Write 'Append
    $nLungo = lungo()
  
  Endif
  Seek #fl, $nLungo * lunghezzadelfile
  Write #fl, $sNome & $sCognome & $sEta & $sSposato
  fl.Close
  Inc $nLungo
  SpinBox1.MaxValue = $nLungo
  TextBox1.Text = ""
  TextBox2.Text = ""
  TextBox3.Text = ""
  TextBox4.Text = ""
  
End

Private Function lungo() As Long
  
  Dim fl As File  
  Dim nomedelfile As String
  
  nomedelfile = User.Home &/ Application.Name &/ "mioFile.dat"
  fl = Open nomedelfile For Read
  Return Lof(fl) / lunghezzadelfile    
  
End


Private Function fissaScrivo(valore As String) As String
  
  Dim i As Integer
  
  If Len(valore & "\t") < 20 Then
    i = 20 - Len(valore & "\t")        
    Return valore & "\t" & Space$(i)
  Else If Len(valore & "\t") = 20 Then
    Return valore & "\t"  
  Else If Len(valore & "\t") > 20 Then
    Return Left$(valore, 19) & "\t"
  Else
    Quit    
  Endif  
    
End

Private Function eta(valore As String) As String
  
  If IsNumber(valore) Then
    Return valore & "\t"
  Else
    Message.Info("L'età deve essere un numero")
    TextBox3.Text = ""
    TextBox3.SetFocus
  Endif
  
End

Private Function sposi(valore As String) As String
  
  If valore = "S" Or valore = "N" Then
    Return valore & "\t"
  Else
    Message.Info("Immettere una S per si oppure una N per no")
    TextBox4.Text = ""
    TextBox4.SetFocus
  Endif
  
End



'' LEGGE
Public Sub Button2_Click()

  Dim i As Integer
  Dim fl As File  
  Dim nomedelfile, s As String
  Dim sDati As String[]
  
  
  nomedelfile = User.Home &/ Application.Name &/ "mioFile.dat"
  fl = Open nomedelfile For Read  
  i = CInt(SpinBox1.Text) - 1
  Seek #fl, lunghezzadelfile * i
  s = Read #fl, lunghezzadelfile
  sDati = Split(s, "\t", "", True, False)
  $sNome = Trim$(sDati[0])
  $sCognome = Trim$(sDati[1])
  $sEta = Trim$(sDati[2])
  $sSposato = Trim$(sDati[3])
  TextBox1.Text = $sNome
  TextBox2.Text = $sCognome
  TextBox3.Text = $sEta
  TextBox4.Text = $sSposato
  

End


Questa più o meno la Form main (vedi istantanea allegata)
:Ciao:
Titolo: Re: Comando OPEN - Aprire un file (Read e Write) in modalità RANDOM
Inserito da: vuott - 17 Febbraio 2015, 20:43:13
Io intendevo più o meno questo (rimanendo in tema VB):

Devi risolvere questa questione posta da Top Fuel
come la mettiamo se leggiamo un record, ne cambiamo la lunghezza e poi lo riscriviamo sul file? Sopratutto se non è l'ultimo e sopratutto se è diventato più lungo perchè magari abbiamo allungato una stringa aggiungendo delle parole?
No, non è il record ad essere più lungo, è la lunghezza di un componente del record a variare. Usando le strutture di Gambas con le variabili stringa di Gambas, se in una ci scrivo "Vuott", questa occupa 5 byte, se dopo ci scrivo "Pastrank" l'occupazione diventa di 8 byte, se lo scrivo sul file il nuovo record sovrascriverà i prime 3 byte del record successivo, a meno che di spostare avanti di 3 byte tutto il contenuto seguente del file. Con i record a lunghezza fissa del VB questo problema non c'è, perchè se il contenuto della stringa è minore della lunghezza il restante viene riempito con caratteri fittizi, se è invece più lunga l'eccedenza viene troncata.

In fondo l'amico Top Fuel non nega ovviamente che con Gambas non si possa ottenere il medesimo risultato, dice semplicemente che in VB v'è l'opzione RANDOM con la connessa procedura ed istruzioni della lettura/scrittura di file che provvede lei a fare i lavoraccio dei dovuti calcoli, non solo per leggere, ma soprattutto per scrivere dati il cui numero può variare all'interno dei campi della struttura tipo dichiarati come Stringhe a lunghezza fissa. La lunghezza fissa porrebbe degli argini, dei punti di riferimento per la scrittura e per la lettura certa.


Vorrei solo far notare che la frase
...è la lunghezza di un componente del record a variare...
detta così, a mio modesto avviso non appare precisa, confonde la comprensione della lettura del ragionamento di Top Fuel, poiché sia i campi dichiarati come tipi nativi sia quelli dichiarati come tipo Stringa a lunghezza fissa non sono modificabili, a meno di non dichiarare un nuovo oggetto Struttura tipo. La stessa dimensione della Struttura tipo (insomma quella che VB chiama Record) è determinata dalla somma della memoria occupata dai "tipi" in cui sono stati dichiarati i campi ...alla quale presumibilmente si aggiungono gli eventuali allineamenti dei campi all'interno del Record (la Struttura tipo).
Dalla discussione questa cosa dapprima non è chiara; si chiarisce successivamente quando l'amico Top Fuel lascia intendere che si tratta di modifica del numero di dati significativi all'interno di uno o più campi dichiarati come di tipo Stringa a lunghezza fissa.
Titolo: Re: Comando OPEN - Aprire un file (Read e Write) in modalità RANDOM
Inserito da: Gianluigi - 18 Febbraio 2015, 00:41:34
Questo dovrebbe più o meno funzionare come chiedeva Top Fuel.
Funziona cosi (almeno spero):
Scrivere i dati e agire sul pulsante Aggiungi record per inserire un nuovo record nel file. Agendo sullo SpinBox e poi sul pulsante Leggi si possono leggere i vari record salvati. Agendo sul pulsante Pulisci si cancellano i dati scritti nelle textbox per poterci scrivere più agevolmente. Richiamare il record che si vuol sostituire in tutto o in parte agendo sullo SpinBox e su Leggi per trovarlo quindi dopo aver apportato i cambiamenti agire sul pulsante Sostituisci record. I record non si possono eliminare ma se un record non serve più lo si può marcare da sostituire per poi appunto riscriverci sopra un altro record con la procedura di sostituzione vista prima. Col pulsante Cerca record libero si possono trovare i record sostituibili (se ci sono) NB: trova la prima occorrenza.

CHANGELOG:
Ho messo trim sui valori passati alle funzioni.
Ho tolto un bug sull'età permettendo anche di inserire età superiori ai cento anni.
Ho affinato i controlli sui dati immessi che ora sembrano funzionare :)
Ora l'operatore viene rassicurato sul buon fine delle operazioni.

CHANGELOG 2:
Il messaggio che appariva quando si agiva sul pulsante Elimina record era fuorviante (parlava di file al posto di record), ho provveduto a correggerlo.
 :ciao:

PS: L'applicazione è stata rimossa
Titolo: Re: Comando OPEN - Aprire un file (Read e Write) in modalità RANDOM
Inserito da: Gianluigi - 18 Febbraio 2015, 17:46:08
Il codice delle applicazioni postate in precedenza aveva un grande difetto, non teneva conto che ogni volta che si apre un file con Open poi occorre sempre chiuderlo con Close. Scusate tanto ma a mia discolpa chiamo il fatto che non sono pratico nell'uso di file per memorizzare i record e vi avevo avvisati.  :P
In VB si poteva usare Close preventivamente e se anche ci si dimenticava di chiudere un file anche a causa di un malfunzionamento questo lo chiudeva a prescindere dal nome. In Gambas sembra non potersi fare ma in compenso il codice funzionava lo stesso in quanto comunque ci si riferisce ad un file ben preciso che Gambas evidentemente non riapre se già aperto, bene a sapersi.

Titolo: Re: Comando OPEN - Aprire un file (Read e Write) in modalità RANDOM
Inserito da: Top Fuel - 18 Febbraio 2015, 22:27:38
Ci ho guardato, tutto bene ma con 3 appunti:

1- Non è obbligatorio che tutti i campi debbano essere riempiti, si può anche lasciarli vuoti.
2- Per eliminare un singolo record non c'è bisogno di riscrivere tutto il file, basta spostare di una posizione indietro tutti i record seguenti.
3- Perchè non hai usato una struttura?

Per il resto direi un buon lavoro. :)
Titolo: Re: Comando OPEN - Aprire un file (Read e Write) in modalità RANDOM
Inserito da: vuott - 19 Febbraio 2015, 00:50:26
3- Perchè non hai usato una struttura?

...effettivamente questa è una domanda giusta e che è sorta anche in me.   (http://levipere.com/wp-content/plugins/smilies-themer/Axendr/whistling.gif)
Ma forse la risposta sta nel fatto che Gianluigi utilizza solo variabili di tipo Stringa, quindi di tipo omogeneo; i valori delle quali vengono poi raccolti insieme da un vettore di tipo Stringa:
Codice: gambas [Seleziona]
 Dim sDati As String[]



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 !!!  (http://levipere.com/wp-content/plugins/smilies-themer/Axendr/icon_rolleyes.gif)
Titolo: Re: Comando OPEN - Aprire un file (Read e Write) in modalità RANDOM
Inserito da: Gianluigi - 19 Febbraio 2015, 14:41:50
@Top Fuel e @Vuott

E' proprio in questi due post a seguire che spiego l'uso delle stringhe...
Dovuto al fatto che non capisco niente di stream...

Scusate se riprendo la discussione con apparente ritardo ma ero rimasto in attesa di eventuali vostri nuovi post.
Io fin'ora se dovevo memorizzare dei dati in una mia applicazione ricorrevo ad un database.
Sono pertanto digiuno di quanto qui voi siete a discutere e anticipo le mie scuse per eventuali castronerie.
...
Quindi se fosse scritto su un file di testo sarebbe come una roba così:...
...


...
Scusate tutti quanti ma a causa della niubbaggine stento a ben spiegare quello che intendo dire.
Io intendevo più o meno questo (rimanendo in tema VB):
...

… intendevo riferirmi sempre a “se fosse un file di testo”...

...
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? Il fatto che poi io non ne abbia tenuto conto nel codice non inficia l'esempio che potrebbe essere sviluppato.
Si potrebbe leggere dato per dato, inteso come campo, se ci sono cambiamenti ecc... Bada bene non sto parlando di codice efficiente ma di possibilità.

Ribadisco il mio è un esempio con stringhe per spiegare in pratica cosa chiedevo in aiuto.
Comunque mi rimane difficile capire poi come fare a utilizzare una forma di split se non usiamo le stringhe.

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:

Citazione
3- Perchè non hai usato una struttura?

A parte che io di strutture ne capisco punto, comunque ti ha già risposto vuott
Sarebbe molto gradita versione aggiornata e corretta del mio esempio

Citazione
Per il resto direi un buon lavoro. :)
Grazie lo stesso, anche se è una pietosa bugia  :-*

3- Perchè non hai usato una struttura?
...effettivamente questa è una domanda giusta e che è sorta anche in me.  
Ma forse la risposta sta nel fatto che Gianluigi utilizza solo variabili di tipo Stringa, quindi di tipo omogeneo; i valori delle quali vengono poi raccolti insieme da un vettore di tipo Stringa:
Codice: gambas [Seleziona]
 Dim sDati As String[]


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 !!!  

Spiegazione già data circa l'uso delle stringhe a parte, cosa intendi parlando di 8 byte? Le stringhe (al di sotto delle 127 lettere) non occupano un byte ogni carattere?

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?

Grazie dell'attenzione.
:ciao:
Titolo: Re: Comando OPEN - Aprire un file (Read e Write) in modalità RANDOM
Inserito da: Top Fuel - 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ì... :)
Titolo: Re: Comando OPEN - Aprire un file (Read e Write) in modalità RANDOM
Inserito da: vuott - 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
Titolo: Re: Comando OPEN - Aprire un file (Read e Write) in modalità RANDOM
Inserito da: Gianluigi - 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:
Titolo: Re: Comando OPEN - Aprire un file (Read e Write) in modalità RANDOM
Inserito da: vuott - 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 !
Titolo: Re: Comando OPEN - Aprire un file (Read e Write) in modalità RANDOM
Inserito da: Gianluigi - 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:
Titolo: Re: Comando OPEN - Aprire un file (Read e Write) in modalità RANDOM
Inserito da: vuott - 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
Titolo: Re: Comando OPEN - Aprire un file (Read e Write) in modalità RANDOM
Inserito da: vuott - 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.
Titolo: Re: Comando OPEN - Aprire un file (Read e Write) in modalità RANDOM
Inserito da: Gianluigi - 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...
Titolo: Re: Comando OPEN - Aprire un file (Read e Write) in modalità RANDOM
Inserito da: Top Fuel - 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.
Titolo: Re: Comando OPEN - Aprire un file (Read e Write) in modalità RANDOM
Inserito da: vuott - 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:  (http://forum.ubuntu-it.org/images/smilies/iospalo.gif)  sbagliare, imprecare, riprovare.
Titolo: Re: Comando OPEN - Aprire un file (Read e Write) in modalità RANDOM
Inserito da: Gianluigi - 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:
Titolo: Re: Comando OPEN - Aprire un file (Read e Write) in modalità RANDOM
Inserito da: vuott - 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.    :-\
Titolo: Re: Comando OPEN - Aprire un file (Read e Write) in modalità RANDOM
Inserito da: Top Fuel - 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.
Titolo: Re: Comando OPEN - Aprire un file (Read e Write) in modalità RANDOM
Inserito da: Gianluigi - 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 !!!  (http://levipere.com/wp-content/plugins/smilies-themer/Axendr/icon_rolleyes.gif)

...
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:

Titolo: Re: Comando OPEN - Aprire un file (Read e Write) in modalità RANDOM
Inserito da: Gianluigi - 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
Titolo: Re: Comando OPEN - Aprire un file (Read e Write) in modalità RANDOM
Inserito da: vuott - 24 Febbraio 2015, 11:56:38
La sola variabile Stringa invece occupa ...

Riguardo alla Stringa possiamo dire che una Stringa formata da qualsiasi quantità di caratteri, occupa *sempre* in quanto variabile quegli 8 byte, perché essa è in realtà un puntatore a una struttura più complessa (che contiene, fra l'altro, la lunghezza della stringa).



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
Bisogna distinguere lo spostamento automatico del puntatore interno del file in caso di lettura o di scrittura del file dallo spostamento del puntatore interno del file in modo... manuale: con la funzione Seek.

Insomma la funzione Seek consente di posizionare il puntatore su qualsiasi byte del file/stream.
E' chiaro che nel caso in cui, utilizzando il Seek, il puntatore interno non venga impostato sul primo byte utile per la corretta lettura o scrittura del file, il valore letto o scritto risulterà sfalzato, errato. Ciò però non toglie che io - appunto con Seek - possa leggere una parte o scrivere solo su una parte dell'intero valore sul file/stream.

Si faccia al riguardo il seguente esperimento.
Codice: gambas [Seleziona]
Public Sub Main()

  Dim fl As File
  Dim i As Integer
  
    fl = Open "/tmp/miofile" For Create
    fl.Close
 
    fl = Open "/tmp/miofile" For Read Write
    
    Write #fl, 9999 As Short
    Write #fl, 444444 As Integer
    Write #fl, 9999 As Short
    
    Seek #fl, 3
    Read #fl, i
    Print i, Hex(i, 4)
    
' Ora leggiamo il valore Intero precedentemente scritto (44444) dal suo primo byte utile:
    Seek #fl, 2
    Read #fl, i
    Print i, Hex(i, 4)

    fl.Close

End
Titolo: Re: Comando OPEN - Aprire un file (Read e Write) in modalità RANDOM
Inserito da: Top Fuel - 24 Febbraio 2015, 12:08:38
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

Ho i miei tempi, lo sai. ;D
Titolo: Re: Comando OPEN - Aprire un file (Read e Write) in modalità RANDOM
Inserito da: Top Fuel - 24 Febbraio 2015, 16:06:50
Et voilà, eccovi in allegato la versione riveduta e stravolta del programma di Gianluigi con l'uso delle variabili strutturate. :coder:
Ditemi cosa ne pensate. :)
Titolo: Re: Comando OPEN - Aprire un file (Read e Write) in modalità RANDOM
Inserito da: Gianluigi - 24 Febbraio 2015, 21:32:00
@Top Fuel

Guarda mi dispiace ma il tuo programma inserisce dati a casaccio, ti basta fare una prova semplice: Invece di popolarlo in modo casuale scrivi i dati in modo che si capisca il record vale a dire inserisci anche il numero nelle stringhe (tipo nome Rec1) e ti accorgerai che non funge.  :-\
Penso che parte dei problemi derivino proprio dall'uso delle ValueBox sono infide e poco controllabili ti sconsiglio dall'usarle meglio le sane TextBox che poi le controlli come meglio vuoi.
Se inserisco un'età errata ad esempio invece di 47 470 me la accetta e poi mette un valore inferiore a 255.
Che le value non funzionino a dovere se guardi la mia applicazione allegata vedi che se inserisci un numero superiore te lo cambia in quello ultimo corrente e se poi agisci sulle spin si sposta correttamente mentre il tuo va a casaccio non so se per colpa delle valuebox delle strutture o cosa.
Mi da errore su sostituzione record “Unknown symbol bEta in datipersonaliold in effetti avresti dovuto scrivere betaOld credo.
E poi anche aggiustando bEtaOld non sostituisce il record.
Invece le singole sostituzioni apparentemente funzionano.

Un piccolo appunto sul booleano di sposato è incontrollabile perché se uno si dimentica di inserire il dato è come se dicesse che non è sposato.

Malgrado il grande merito di avermi finalmente ben spiegato come si devono mischiare i dati stringa con gli altri (anche se potevate dirlo subito senza fare tanto gli indiani  >:( ) per come la vedo io sei rimandato ad Ottobre.  ;D
Comunque anche ora che ho capito continuo a non comprendere a cosa servano le strutture, che non siano proprio queste ultime che ti danno problemi? Io non usandole...

Ti allego una versione funzionante che puoi usare per studiare prima di presentarti agli esami.  :P

Una cosa però la devo proprio far notare: Il ciclo che elimina i primi record ci mette di più (circa un centesimo e mezzo di secondo) la versione con l'età e sposato byte rispetto alla versione tutta stringhe.
 :ciao:

PS: Ma non mi avevi detto che le stringhe fisse non servivano  ???
Titolo: Re: Comando OPEN - Aprire un file (Read e Write) in modalità RANDOM
Inserito da: Gianluigi - 24 Febbraio 2015, 22:11:49
Credo di aver capito dove sta l'inghippo.
E' colpa della routine di  sostituzione del record che lo aggiunge invece di cambiarlo e scombussola tutto avevo fatto delle sostituzioni e mi ero ritrovato dei record che non avevo inserito.
Ho trovato un altro bug se sulla value delle spin metti un numero maggiore dei record effettivamente presenti ti da errore di “end of file” devi gestire l'immissione.
 :ciao:
Titolo: Re: Comando OPEN - Aprire un file (Read e Write) in modalità RANDOM
Inserito da: Top Fuel - 24 Febbraio 2015, 22:37:51
Andava testato un pò più a fondo ed inoltre la gestione degli errori non l'abbiamo implementata per niente.
Comunque io mi sono limitato a riscrivere le TUE routine usando le strutture quindi non ci vuole molto a capire da dove proviene l'errore... :P :P
Titolo: Re: Comando OPEN - Aprire un file (Read e Write) in modalità RANDOM
Inserito da: Gianluigi - 24 Febbraio 2015, 22:54:35
Le mie applicazioni sono li postate ben prima della tua a disposizione di chiunque voglia provarle.
E se lo faranno avranno modo di accorgersi:
1 – Che tu racconti le bugie.    :nono:
2 - Che io non devo gestire gli errori perché semplicemente li prevengo.  :P

Comunque ti voglio bene ugualmente perché mi hai insegnato qualcosa di nuovo  :-*
Titolo: Re: Comando OPEN - Aprire un file (Read e Write) in modalità RANDOM
Inserito da: vuott - 24 Febbraio 2015, 22:58:27
Comunque anche ora che ho capito continuo a non comprendere a cosa servano le strutture...

1)

 Struttura : area_riservata_di_memoria_di_tipi_di_dati_non_omogenei = Array : area_riservata_di_memoria_di_tipi_di_dati_omogenei


2)
 
  Da ciò consegue anche il principio enunciato da md9327: " Classes ex solis proprietatibus sunt Structurae ", ossia creando una Classe contenente soltanto Proprietà/Variabili (quindi priva di metodi e di eventi) si ottiene un'area riservata di memoria corrispondente sostanzialmente ad una Struttura.


3)

 Tieni conto che le Strutture sono spesso richieste nell'uso di funzioni contenute da librerie esterne.
 Pertanto, volendo utilizzare le risorse esterne di alcune API, non se ne può prescindere (salvo voler utilizzare in loro sostituzione la funzione Alloc() congiuntamente con i Puntatori e i Memory Stream.... ma questa è un'altra storia).


Titolo: Re: Comando OPEN - Aprire un file (Read e Write) in modalità RANDOM
Inserito da: Gianluigi - 24 Febbraio 2015, 23:12:49
Comunque anche ora che ho capito continuo a non comprendere a cosa servano le strutture...

1)
 Struttura : area_riservata_di_memoria_di_tipi_di_dati_non_omogenei = Array : area_riservata_di_memoria_di_tipi_di_dati_omogenei

2)
  Da ciò ne consegue anche il principio enunciato da md9327: " Classes ex solis proprietatibus sunt Structurae ", ossia creando una Classe contenente soltanto Proprietà/Variabili (quindi priva di metodi e di eventi) si ottiene un'area riservata di memoria corrispondente sostanzialmente ad una Struttura.

3)
 Tieni conto che le Strutture sono spesso richieste nell'uso di funzioni contenute da librerie esterne.
 Pertanto, volendo utilizzare le risorse esterne di alcune API, non se ne può prescindere (salvo voler utilizzare in loro sostituzione la funzione Alloc() congiuntamente con i Puntatori e i Memory Stream.... ma questa è un'altra storia).

Grazie vuott, in effetti così come da te esposto più o meno lo sapevo teoricamente non sapendo nulla o quasi di quello per cui sono state implementate.
Io in effetti mi riferivo all'uso di dette strutture (denominate UDT in VB se ricordo bene e li molto usate) in Gambas in questo contesto non mi sembra che siano particolarmente utili ecco... :-\

PS: Avevo letto quanto scritto da md9327 e aveva detto qualcosa di simile anche riguardo ai moduli.

 :ciao:
Titolo: Re: Comando OPEN - Aprire un file (Read e Write) in modalità RANDOM
Inserito da: vuott - 24 Febbraio 2015, 23:31:47
... in Gambas in questo contesto non mi sembra che siano particolarmente utili ecco...

Mah........ diciamo che sono poco utilizzate.  Questo sì.

Come puoi ben immaginare, le Strutture possono essere utilizzate anche all'interno di vettori di Strutture.
Titolo: Re: Comando OPEN - Aprire un file (Read e Write) in modalità RANDOM
Inserito da: Gianluigi - 25 Febbraio 2015, 12:01:07
... in Gambas in questo contesto non mi sembra che siano particolarmente utili ecco...

Mah........ diciamo che sono poco utilizzate.  Questo sì.

Come puoi ben immaginare, le Strutture possono essere utilizzate anche all'interno di vettori di Strutture.

Qualche velo inizia a cadere e la nebbia a farsi meno fitta...

Guardate un po qui:  :-[

Codice: gambas [Seleziona]


Public Sub Form_Open()  
  
  scrivi
  leggi  
  
End


Public Sub scrivi()
  
  Dim fl As File  
  Dim nomedelfile As String
  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    
  Dim s1 As String = "Pippo"
  Dim s2 As String = "Pluto"
  
  
  If Not Exist(User.Home &/ Application.Name) Then
    Mkdir User.Home &/ Application.Name
  Endif
  nomedelfile = User.Home &/ Application.Name &/ "mioFile.dat"
  If Not Exist(nomedelfile) Then
    fl = Open nomedelfile For Create    
  Else
    fl = Open nomedelfile For Write      
  Endif
  Seek #fl, 0
  Write #fl, b As Byte
  Write #fl, s As Short
  Write #fl, i As Integer
  Write #fl, l As Long
  Write #fl, s1, 10
  Write #fl, s2, 10
  fl.Close      
  
End

Public Sub leggi()
  
  Dim fl As File  
  Dim nomedelfile As String
  Dim b As Byte
  Dim s As Short
  Dim i As Integer
  Dim l As Long
  Dim s1, s2 As String
  
  nomedelfile = User.Home &/ Application.Name &/ "mioFile.dat"
  fl = Open nomedelfile For Read
  Seek #fl, 0
  b = Read #fl As Byte
  's = Read #fl As Short
  'i = Read #fl As Integer
  Seek #fl, 7
  l = Read #fl As Long
  Seek #fl, 25
  s2 = Read #fl, 10
  fl.Close
  Print b, l, s2 ' bisognerebbe scriverlo Trim(s2) ma così si comprende che ci pensa lo stesso Gambas a riempire (come fa VB o no?).
  
End


Posso tranquillamente affermare che praticamente tutto quello qui da me sostenuto erano delle beneamate …  :'(

Sarà bene ch'io vada a studiare le strutture...  :-[

Cosa mi suggerite, chiedo ai moderatori di cancellare questa discussione per pietà nei miei confronti?
Titolo: Re: Comando OPEN - Aprire un file (Read e Write) in modalità RANDOM
Inserito da: Top Fuel - 25 Febbraio 2015, 15:25:16
Alla fine tutti i nodi vengono al pettine. ;D ;D
In ogni caso io continuo a sostenere che le strutture sono più facili da maneggiare e richiedono meno codice, solo che rispetto alle stringhe e basta richiedono dei controlli differenti e più mirati.
Poi alla fine c'è sempre sql che risolve. ;D ;D
Comunque Seek serve solo per posizionarsi nel file alla prima variabile da scrivere/leggere, poi non serve più perchè il puntatore interno al file si posiziona sul byte seguente all'ultimo letto, quindi in automatico sulla variabile seguente.
Titolo: Re: Comando OPEN - Aprire un file (Read e Write) in modalità RANDOM
Inserito da: Gianluigi - 25 Febbraio 2015, 19:24:26
Credo di aver compreso cosa significavano fin dal principio di questa discussione sia pastrank che vuott.
Anche Gambas offre le stringhe a lunghezza fissa (più o meno, in effetti devi assicurarti che la stringa non sfori), rimanendo sul tema il codice a seguire lo rende molto evidente.
Anche il mio socio coautore Top Fuel aveva le sue ragioni nel caldeggiare l'uso delle strutture che semplificano il codice.
Con questo spero di non aver ulteriormente aggravato la mia già scarsa credibilità.

Codice: gambas [Seleziona]

Public Struct miaStruttura
  Nome As String
  Cognome As String
  Eta As Byte
  Stato As Byte  
End Struct
Private Agenda As New MiaStruttura

Private nomedelfile As String

Public Sub Form_Open()  
  
  scrivi
  leggi  
  
End


Public Sub scrivi()
  
  Dim fl As File    
  Dim b As Byte
  
  ' Crea un file temporaneo se già c'è
  ' lo elimina, se da errore esce.
  nomedelfile = "/tmp" &/ "mioFile.dat"  
  If Exist(nomedelfile) Then Try Kill nomedelfile  
  If Error Then Quit  
  ' Apre il file in creazione
  fl = Open nomedelfile For Create    
  ' popola nove record
  With Agenda
    For b = 0 To 8
      .Nome = "Nome" & CStr(b + 1)
      Write #fl, .Nome, 10
      .Cognome = "Cognome" & CStr(b + 1)
      Write #fl, .Cognome, 10
      .Eta = 20 + b
      Write #fl, .Eta As Byte
      .Stato = b Mod 2
      Write #fl, .Stato As Byte
    Next
  End With
 
  fl.Close      
  
End

Public Sub leggi()
  
  Dim fl As File  
  Dim n, c As String
  Dim b, e, s As Byte  
  ' Apre il file in lettura
  fl = Open nomedelfile For Read
  ' Legge i nove record e li scrive
  ' in console in modo che appaiano
  ' affiancati i dati puliti e quelli
  ' con i caratteri inseriti da Gambas.
    For b = 0 To (Lof(fl) - 1) Step 22
      Seek #fl, b
      n = Read #fl, 10
      c = Read #fl, 10
      e = Read #fl As Byte
      s = Read #fl As Byte      
      Print Trim(n), Trim(c), e, s, "|" & n, c, e, s
    Next
      
  fl.Close
  
End


Titolo: Re: Comando OPEN - Aprire un file (Read e Write) in modalità RANDOM
Inserito da: vuott - 25 Febbraio 2015, 21:34:15
Relativamente al tuo ultimo codice sollevo due problemi.

Il primo ...va be'... è 'na fesseria:
nella sotto-procedura  leggi()  è rimasto appeso un solitario:
Codice: gambas [Seleziona]
 With Agenda
....
End With



Il secondo è più complesso.
Lanciando il programma, in console ho una serie in colonna di sgradevoli caratteri accanto a quelli alfanumerici, del tipo:

|Nome1^@^@^@^@^@   Cognome1^@^@

Perché li hai voluti inserire ?    :-\
Titolo: Re: Comando OPEN - Aprire un file (Read e Write) in modalità RANDOM
Inserito da: Gianluigi - 25 Febbraio 2015, 22:16:18
@vuott,
Vedo che malgrado i miei sforzi (eppure giuro che mi impegno) la credibilità continua a scendere, e va buò.
With e End With sono il risultato della deprecabile abitudine del copia incolla, che malgrado cerchi di abbandonare continua a perseguitarmi.
Per quanto riguarda i dati puliti e a fianco quelli lasciati “nature”, deduco dalla tua domanda che quei “sgradevoli caratteri” non rappresentano il “riempitivo” che Gambas utilizza per marcare gli spazi, cosa che io invece credevo.
E' appunto perché io credevo fossero i marca byte che li ho mostrati a fianco dei risultati corretti.

PS: Riguardo agli With ho provveduto a rimuoverli. Grazie della segnalazione.
Titolo: Re: Comando OPEN - Aprire un file (Read e Write) in modalità RANDOM
Inserito da: vuott - 25 Febbraio 2015, 23:57:39
...deduco dalla tua domanda che quei “sgradevoli caratteri” non rappresentano il “riempitivo” che Gambas utilizza per marcare gli spazi, cosa che io invece credevo.
E' appunto perché io credevo fossero i marca byte che li ho mostrati a fianco dei risultati corretti.

...m...marca byte ?     :rolleyes:

Quei caratteri strani sono (lo si nota anche dall'aspetto grafico) la rappresentazione stringa di byte con valore 0 (zero).
Li hai ottenuti imponendo nelle righe ove scrivi con Write, come ad esempio:
Codice: gambas [Seleziona]
Write #fl, .Nome, 10

e più segnatamente al terzo parametro, un valore superiore ai dati da scrivere presenti nel membro della Struttura.
Vedi anche qui:
 http://www.gambas-it.org/wiki/index.php?title=Write#Scrivere_una_quantit.C3.A0_superiore_ai_dati_in_possesso

Se vuoi impostare gli spazi dopo i caratteri alfanumerici presenti nei membri della Struttura, li devi aggiungere in modo preciso e puntuale: le modalità per farlo - come sai - sono più di una. 
Titolo: Re: Comando OPEN - Aprire un file (Read e Write) in modalità RANDOM
Inserito da: Top Fuel - 26 Febbraio 2015, 00:07:33
Riposto in allegato la versione riveduta e corretta del programma, con i controlli per evitare l'età sballata e l'end of file più altre piccole modifiche.
Adesso pare funzionare meglio. :)
Titolo: Re: Comando OPEN - Aprire un file (Read e Write) in modalità RANDOM
Inserito da: Gianluigi - 26 Febbraio 2015, 00:11:57
...deduco dalla tua domanda che quei “sgradevoli caratteri” non rappresentano il “riempitivo” che Gambas utilizza per marcare gli spazi, cosa che io invece credevo.
E' appunto perché io credevo fossero i marca byte che li ho mostrati a fianco dei risultati corretti.

...m...marca byte ?     :rolleyes:

Quei caratteri strani sono (lo si nota anche dall'aspetto grafico) la rappresentazione stringa di byte con valore 0 (zero).
Li hai ottenuti imponendo nelle righe ove scrivi con Write, come ad esempio:
Codice: gambas [Seleziona]
Write #fl, .Nome, 10

e più segnatamente al terzo parametro, un valore superiore ai dati da scrivere presenti nel membro della Struttura.
Vedi anche qui:
 http://www.gambas-it.org/wiki/index.php?title=Write#Scrivere_una_quantit.C3.A0_superiore_ai_dati_in_possesso

Se vuoi impostare gli spazi dopo i caratteri alfanumerici presenti nei membri della Struttura, li devi aggiungere in modo preciso e puntuale: le modalità per farlo - come sai - sono più di una. 

Forse c'è un qui pro quo.
Io ho volutamente segnato più spazio stringa (10) al posto dei 5 usati per il nome e 8 per il cognome proprio per rappresentare una stringa a lunghezza fissa che possa poi all'occorrenza essere sostituita con una più lunga senza compromettere la struttura del record.
Ora io non sono così addentro a Gambas per sapere se ci sono altri modi per sostituire al meglio una stringa in un record senza sovrascrivere la stringa (o il valore) successiva, però così come ho fatto posso tranquillamente sostituire (sempre rimanendo in questo caso entro i dieci caratteri, ma ne puoi mettere quanti abbisognano) le stringhe già scritte con altre più lunghe, che poi è il tema della discussione.

Se aggiungi al codice che ho postato la routine “sostituisci”:
Codice: gambas [Seleziona]

Public Sub sostituisci()
 
  Dim fl As File   
  Dim b As Byte
 
 
  ' Apre il file.
  nomedelfile = "/tmp" &/ "mioFile.dat"     
  ' Apre il file in scrittura
  fl = Open nomedelfile For Write     
  ' cambia i nove record
  With Agenda
    For b = 0 To 8
      .Nome = "NomeSost" & CStr(b + 1)
      Write #fl, .Nome, 10
      .Cognome = "CognSost" & CStr(b + 1)
      Write #fl, .Cognome, 10
      .Eta = 30 + b
      Write #fl, .Eta As Byte
      .Stato = 2
      Write #fl, .Stato As Byte
    Next
  End With
 
  fl.Close     
 
End



E vari così il codice Form_Open:

Codice: gambas [Seleziona]


Public Sub Form_Open() 
 
  scrivi
  leggi 
  sostituisci
  leggi
 
End


Dovresti vedere che cosa intendo dire.

Avevo visto quanto mi hai segnalato ma così come ho fatto mi sembra funzionare bene.
Titolo: Re: Comando OPEN - Aprire un file (Read e Write) in modalità RANDOM
Inserito da: Gianluigi - 26 Febbraio 2015, 00:16:32
Riposto in allegato la versione riveduta e corretta del programma, con i controlli per evitare l'età sballata e l'end of file più altre piccole modifiche.
Adesso pare funzionare meglio. :)

Ciao socio,
sono fuso ora vado a dormire, poi domani con calma mi vedo tutto.
Per ora ti ringrazio, buonanotte a tutti
 :sleepy:
Titolo: Re: Comando OPEN - Aprire un file (Read e Write) in modalità RANDOM
Inserito da: vuott - 26 Febbraio 2015, 01:34:12
Io ho volutamente segnato più spazio stringa (10) al posto dei 5 usati per il nome e 8 per il cognome proprio per rappresentare una stringa a lunghezza fissa che possa poi all'occorrenza essere sostituita con una più lunga senza compromettere la struttura del record.
Capisco.
Ad ogni modo dovresti trovare la maniera per evitare che quei caratteri di riempimento vengano eventualmente riportati e scritti in console.
Titolo: Re: Comando OPEN - Aprire un file (Read e Write) in modalità RANDOM
Inserito da: Gianluigi - 26 Febbraio 2015, 10:24:28
Io ho volutamente segnato più spazio stringa (10) al posto dei 5 usati per il nome e 8 per il cognome proprio per rappresentare una stringa a lunghezza fissa che possa poi all'occorrenza essere sostituita con una più lunga senza compromettere la struttura del record.
Capisco.
Ad ogni modo dovresti trovare la maniera per evitare che quei caratteri di riempimento vengano eventualmente riportati e scritti in console.

Allora proprio non riesco a spiegare ciò che voglio dire:
Nel codice ho scritto:
Codice: gambas [Seleziona]

  '…
  ' affiancati i dati puliti e quelli
  ' con i caratteri inseriti da Gambas.
  For b = 0 To (Lof(fl) - 1) Step 22
    Seek #fl, b
    n = Read #fl, 10
    c = Read #fl, 10
    e = Read #fl As Byte
    s = Read #fl As Byte     
    Print Trim(n), Trim(c), e, s, "|" & n, c, e, s
  Next 

Se il codice ti funziona correttamente Print ti dovrebbe stampare la colonna pulita (basta usare Trim)  e a destra, separata da una barra verticale, quella nature realmente presente nel file e che mostra visivamente cosa fa Gambas dietro le quinte per “marcare lo spazio” della stringa “a lunghezza fissa”.
E' una cosa voluta per aiutare nella comprensione, ma sembra che invece di aiutare confonda, cosa che vorrei evitare.
Sono a chiederti, ammesso che quanto da me scritto non sia errato, come posso fare per rendere il mio discorso comprensibile a tutti?
Titolo: Re: Comando OPEN - Aprire un file (Read e Write) in modalità RANDOM
Inserito da: Gianluigi - 26 Febbraio 2015, 11:03:58
Riposto in allegato la versione riveduta e corretta del programma, con i controlli per evitare l'età sballata e l'end of file più altre piccole modifiche.
Adesso pare funzionare meglio. :)

Non ho approfondito più di tanto, ma quando ho visto che dava gli stessi errori della precedente che ho già segnalato, tipo quello su cambia record. Ho smesso di provare e ti chiedo se per caso non hai postato la versione vecchia.
Anche perché vedo che ha lo stesso nome e versione.
E' cosa buona e saggia per evitare di confondersi cambiare il numero alla versione più recente.  ;)

 :ciao:
Titolo: Re: Comando OPEN - Aprire un file (Read e Write) in modalità RANDOM
Inserito da: vuott - 26 Febbraio 2015, 16:37:16
Se il codice ti funziona correttamente Print ti dovrebbe stampare la colonna pulita (basta usare Trim)  e a destra, separata da una barra verticale, quella nature realmente presente nel file e che mostra visivamente cosa fa Gambas dietro le quinte per “marcare lo spazio” della stringa “a lunghezza fissa”.
E' una cosa voluta per aiutare nella comprensione
Va bene. Ora ho capito lo scopo.
Va bene.
Titolo: Re: Comando OPEN - Aprire un file (Read e Write) in modalità RANDOM
Inserito da: Gianluigi - 26 Febbraio 2015, 17:32:51
Se il codice ti funziona correttamente Print ti dovrebbe stampare la colonna pulita (basta usare Trim)  e a destra, separata da una barra verticale, quella nature realmente presente nel file e che mostra visivamente cosa fa Gambas dietro le quinte per “marcare lo spazio” della stringa “a lunghezza fissa”.
E' una cosa voluta per aiutare nella comprensione
Va bene. Ora ho capito lo scopo.
Va bene.

Sono contento di essere riuscito a spiegarmi, ma con te è senz'altro più semplice perché di programmazione ne sai, ma con uno che ne sa ancora meno di me...
Penso che parte dell'incomprensione sia dovuta anche al fatto che io mi esprimo in modo non scientifico e poi giustamente la mia credibilità come programmatore...  :)

Gradirei capire se questo tuo va bene si limita al fatto che ora sono riuscito a spiegarmi oppure sei più o meno d'accordo con quanto sostengo?

Occorre una precisazione su quanto ho fin qui detto: se si opera una sostituzione mirata al singolo dato del record questa va fatta portando il SEEK sul primo byte del campo da sostituire, è già stato detto da te ma è meglio ribadirlo perché quanto scritto ultimamente potrebbe aver confuso le acque.
Per verificare con mano cosa intendo si può aggiungere al codice di esempio quest'altra routine:
Codice: gambas [Seleziona]

Public Sub sostituisciUno()
  
  Dim fl As File  
  ' Il percorso
  nomedelfile = "/tmp" &/ "mioFile.dat"      
  ' Apre il file in scrittura
  fl = Open nomedelfile For Write    
  ' cambia il secondo e quarto campo del terzo record
  ' prima si deve portare sul terzo record il n°2 partendo
  ' da zero deve pertanto sommare (22*2) + 10
  Seek #fl, (22 * 2) + 10
  With Agenda    
      .Cognome = "CogSingle3"
      Write #fl, .Cognome, 10
      ' e poi sul quarto
      Seek #fl, (22 * 2) + 10 + 10 + 1
      .Stato = 118
      Write #fl, .Stato As Byte    
  End With
 
  fl.Close      
  
End


Cambiando cosi Form_Open:
Codice: gambas [Seleziona]

Public Sub Form_Open()  
  
  scrivi
  leggi  
  sostituisci
  leggi
  sostituisciUno
  leggi
  
End
Titolo: Re: Comando OPEN - Aprire un file (Read e Write) in modalità RANDOM
Inserito da: vuott - 26 Febbraio 2015, 20:15:35
.... di programmazione ne sai,
Non è affatto così: io sono solo uno che fa prove e tentativi.




Gradirei capire se questo tuo va bene si limita al fatto che ora sono riuscito a spiegarmi oppure sei più o meno d'accordo con quanto sostengo?

Che ti eri spiegato.
Titolo: Re: Comando OPEN - Aprire un file (Read e Write) in modalità RANDOM
Inserito da: Gianluigi - 26 Febbraio 2015, 20:41:50
...
Se vuoi impostare gli spazi dopo i caratteri alfanumerici presenti nei membri della Struttura, li devi aggiungere in modo preciso e puntuale: le modalità per farlo - come sai - sono più di una. 

...
Che ti eri spiegato.

Bene, significa che non sei d'accordo con quanto sostengo.
Ma allora come spieghi che il codice da me qui scritto funziona? Che non va a sovrascrivere il valore successivo? Che si posiziona esattamente dove si desidera e si può andarlo a prendere, cambiarlo in parte o in toto come meglio ci aggrada?
Titolo: Re: Comando OPEN - Aprire un file (Read e Write) in modalità RANDOM
Inserito da: vuott - 26 Febbraio 2015, 23:03:58
Bene, significa che non sei d'accordo con quanto sostengo.

Ho solo affermato che avevo capito la tua intenzione.
Relativamente alle stringhe a lunghezza fissa devo dire che esse non sono in cima alle mie attenzioni in questo periodo. Pertanto, non ho approfondito i vostri codici.
Titolo: Re: Comando OPEN - Aprire un file (Read e Write) in modalità RANDOM
Inserito da: Gianluigi - 27 Febbraio 2015, 14:24:13
Ho rimosso le applicazioni che avevo postato in quanto fuorvianti partendo da presupposti sbagliati.
Invero io le avevo postate nella speranza che qualcuno si prendesse la briga di cambiarle la dove serviva.
Trovo più utile chiudere i miei interventi con quest'ultima precisazione che comunque già appare nelle spiegazioni della wiki (che a mio avviso andrebbe rivista in parte) ma che non avevo inteso nella sua reale portata.
Quando come nel codice postato scriviamo l'istruzione
Codice: gambas [Seleziona]

Write #fl, .Cognome, 10

in realtà facciamo esattamente la stessa cosa che in VB si fa scrivendo
Codice: vb [Seleziona]

LastName as String*10

infatti se noi assegniamo un cognome più corto sia Gambas che VB lo riempono dei caratteri mancanti fino a portarlo a 10 totali e al contrario se noi dovessimo assegnare un cognome più lungo lo troncherebbero. Per poterlo verificare in Gambas basta cambiare questa riga della routine “sostituisciUno” appena sotto “With Agenda” con
Codice: gambas [Seleziona]

.Cognome = "CognomeSingle3"

per constatare come il cognome, essendo più lungo di 10 caratteri, venga troncato automaticamente e non vada a sovrascrivere il valore successivo.
Altra precisazione, sono ritornato alle mie posizioni di partenza riguardo le strutture, non mi riesce proprio di capire a cosa servano, se infatti avete voglia di  cambiare il codice togliendo la struttura (cancellandone tutte le tracce) lasciando solo le variabili vi accorgereste che il codice lavora nello stesso identico modo.

Mia riflessione finale: Ringrazio chi ha postato il quesito e chi vi ha partecipato ora comunque ho una conoscenza più ampia dei file mi si è diradata (in piccola parte) la nebbia riguardo gli stream ho una vaga percezione in più riguardo i puntatori.
Ma ora con maggiore consapevolezza di prima ringrazio ancora di più chi mi mette a disposizione database di tutte le taglie che mi permettono di trattare in sicurezza dati che se lasciati a me e ai file andrebbero sicuramente a ramengo.
 :ciao:
Titolo: Re: Comando OPEN - Aprire un file (Read e Write) in modalità RANDOM
Inserito da: vuott - 27 Febbraio 2015, 16:38:52
...sono ritornato alle mie posizioni di partenza riguardo le strutture, non mi riesce proprio di capire a cosa servano....

La Struttura, variabile strutturata di reminescenza del C, è un tipo derivato che aggrega elementi di tipo diverso. Ci si serve di essa, qualora si abbia necessità di utilizzare un'area riservata di memoria di tipi di dati non omogenei.
http://www.gambas-it.org/smf/index.php?topic=3919.msg35077#msg35077
http://www.gambas-it.org/smf/index.php?topic=3919.msg35108#msg35108


...mi si è diradata (in piccola parte) la nebbia riguardo gli stream...

La variabile Stream si comporta in sostanza in modo identico alla variabile File; tant'è che ne condivide Proprietà e Metodi.
Si differenzia dalla consorella variabile di tipo File per la circostanza che:
* utilizza memoria volatile (non si utilizza per creare un file classico);
* viene utilizzata per leggere e scrivere in aree allocate di memoria puntate da variabili di tipo Puntatore (dereferenziazione).


...ho una vaga percezione in più riguardo i puntatori.

Le variabili di tipo Puntatore restituiscono l'indirizzo di memoria di una variabile o di una area di memoria allocata (riservata) con la funzione Alloc(). Il Puntatore così ci consente di accedere all'area allocata o alla variabile puntata al fine di leggerne o scrivervi dati.
La lettura dei dati, contenuti nell'area riservata puntata da una variabile di tipo Puntatore e più in generale di una variabile puntata da un Puntatore, può avvenire in Gambas in due modi:
* mediante le funzioni specifiche: Byte@(), Short@(), Int@(), etc
* mediante la gestione dei Memory Stream.
La scrittura dei dati all'interno di un'area riservata puntata da una variabile di tipo Puntatore, può avvenire in Gambas - attualmente - in modo esclusivo mediante la gestione dei Memory Stream.


Strutture e Puntatori sono ampiamente utilizzati nel linguaggio C. Pertanto, la loro conoscenza e la capacità della loro gestione è immensamente e sommamente richiesta, utile ed imprescindibile nel caso di dichiarazioni e chiamate di funzioni appartenenti ad API di librerie esterne a Gambas.
Titolo: Re: Comando OPEN - Aprire un file (Read e Write) in modalità RANDOM
Inserito da: Top Fuel - 27 Febbraio 2015, 23:40:51
In ogni caso, lette tutte le varie considerazioni, preferisco ancora le strutture, che secondo me semplificano la vita. Poi ognuno può pensarla come vuole.
Piuttosto, mi piacerebbe leggere il parere di chi ha aperto il topic, che ha lanciato il sasso e poi non si è più fatto sentire...  :-\
Titolo: Re: Comando OPEN - Aprire un file (Read e Write) in modalità RANDOM
Inserito da: Gianluigi - 28 Febbraio 2015, 14:35:55
In ogni caso, lette tutte le varie considerazioni, preferisco ancora le strutture, che secondo me semplificano la vita. Poi ognuno può pensarla come vuole.
Semplificano la vita in che senso? Ti devi spiegare. Io come avevo già avuto modo di dire qui mi limito a considerare le strutture in Gambas all'interno del contesto discusso, mi rendo conto che in altri scenari siano indispensabili, ma ripeto io in Gambas, all'interno delle sue normali procedure mi sembra solo che complichino la vita altro che semplificarla, nella migliore delle ipotesi devi scrivere più codice.

Vuott riportava:
Struttura : area_riservata_di_memoria_di_tipi_di_dati_non_omogenei = Array : area_riservata_di_memoria_di_tipi_di_dati_omogenei

A parte che non considera l'array variant  comunque con le array omogenee io ad esempio posso ordinare i dati con Sort e farci altre cose ma con una struttura cosa ci faccio? Zero o meglio devo scrivere più codice che magari si rallenta pure un pochino chissà.

Citazione
Piuttosto, mi piacerebbe leggere il parere di chi ha aperto il topic, che ha lanciato il sasso e poi non si è più fatto sentire...  :-\

Concordo, sarei curioso anch'io.
 :ciao:
Titolo: Re: Comando OPEN - Aprire un file (Read e Write) in modalità RANDOM
Inserito da: vuott - 28 Febbraio 2015, 14:54:38
A parte che non considera l'array variant...

Questo lo credi tu.
Non tutto però si può utilizzare ovunque e sempre: negli àmbiti che solitamente frequento io, se utilizzo il Variant, le funzioni me lo sbattono in faccia.

Io ho solo cercato di dare una risposta alla tua domanda generale sulle Strutture.



...comunque con le array omogenee io ad esempio posso ordinare i dati con Sort e farci altre cose ma con una struttura cosa ci faccio?
...non puoi paragonare una Struttura ad un Array, poiché la prima a differenza della seconda (lo ripeto per l'ennesima volta) NON è una variabile strutturata di tipi omogenei,

Come ha detto Top Fuel, ognuno usa le risorse che conosce, che meglio conosce o che ritiene più utili ed opportune al momento.
Titolo: Re: Comando OPEN - Aprire un file (Read e Write) in modalità RANDOM
Inserito da: Gianluigi - 28 Febbraio 2015, 15:02:02
Io come avevo già avuto modo di dire qui mi limito a considerare le strutture in Gambas all'interno del contesto discusso, mi rendo conto che in altri scenari siano indispensabili...

 :-\
Titolo: Re: Comando OPEN - Aprire un file (Read e Write) in modalità RANDOM
Inserito da: vuott - 28 Febbraio 2015, 16:02:45
...appunto.
Titolo: Re: Comando OPEN - Aprire un file (Read e Write) in modalità RANDOM
Inserito da: filipsnew - 02 Aprile 2015, 00:24:14
Ma così devi caricare in memoria TUTTO il file per modificare un solo record. ... non mi pare il massimo dell'efficienza, sopratutto se il file è bello grosso.

Tu mi hai chiesto una risorsa ed una procedura efficace, che producesse gli effetti da te sopra indicati; e la mia soluzione rispetta questo criterio.

Inoltre, il caricamento in memoria di grosse quantità byte non mi pare che oggi giorno sia un problema mortale.
Nei miei esempi, presenti nella WIKI, di esecuzione dei file audio con funzioni esterne in alcuni casi si arriva a caricare in memoria anche diverse decine di milioni di byte !



Con la modalità random del VB caricavi in memoria solo il record da modificare e scrivevi nel file solo il record modificato, senza toccare il resto del file.
......vorrei proprio vedere il codice C che c'è dietro quella risorsa.    ;D

@vuott, ringraziamenti sinceri per gli esempi postati.. mi hanno anche consentito di aggiornarmi su alcuni piccole differenze sintattiche rispetto a VB. Condivido il discorso sull'efficienza: oggi è davvero impensabile farsi dei problemi per caricamenti anche di decine di MB (in un programma fatto in .NET p.es. sapeste che oggetti mi capita di caricare, eppure l'esecuzione risulta fluida..). Per il discorso che il random di VB non intacchi la memoria avrei anch'io qualche riserva: se la procedura agisce sull'informazione di un certo flusso di dati, per es. per un inserimento intermedio, pare possibile che esista un algoritmo che riesca a farsi spazio tra due contendenti, facendo riapparire quello "alla destra" come per magia più in là quel tanto che basta, senza intaccare un po' di memoria? ???

Incidentalmente poi, ci si potrebbe al contrario chiedere quanto efficiente (dal punto di vista della risorsa temporale) sia l'andare ad operare sistematicamente su file che, non si dimentichi, risiedono su supporti fissi. Meglio crearsi un oggetto veloce su cui operare (inserire, cancellare ecc.) e poi, quando serve, salvare dove i dati devono essere conservati.
Titolo: Re: Comando OPEN - Aprire un file (Read e Write) in modalità RANDOM
Inserito da: vuott - 02 Aprile 2015, 00:53:01

Incidentalmente poi, ci si potrebbe al contrario chiedere quanto efficiente (dal punto di vista della risorsa temporale) sia l'andare ad operare sistematicamente su file che, non si dimentichi, risiedono su supporti fissi. Meglio crearsi un oggetto veloce su cui operare (inserire, cancellare ecc.) e poi, quando serve, salvare dove i dati devono essere conservati.

Mi pare, caro filipsnew, che ci intendiamo molto bene.    ;)
Titolo: Re: Comando OPEN - Aprire un file (Read e Write) in modalità RANDOM
Inserito da: Gianluigi - 02 Aprile 2015, 10:29:15

Incidentalmente poi, ci si potrebbe al contrario chiedere quanto efficiente (dal punto di vista della risorsa temporale) sia l'andare ad operare sistematicamente su file che, non si dimentichi, risiedono su supporti fissi. Meglio crearsi un oggetto veloce su cui operare (inserire, cancellare ecc.) e poi, quando serve, salvare dove i dati devono essere conservati.

Cioè tu intenderesti qualcosa del genere (vedi allegato)?
 :ciao:

P.S. Nel commentato la dove scritto 100,001 è in realtà 1,000,001
Titolo: Re:Comando OPEN - Aprire un file (Read e Write) in modalità RANDOM
Inserito da: vuott - 04 Ottobre 2015, 15:01:27
Riprendo questa discussione ed in particolare la parte relativa alle Strutture.
E' interessante come Minisini abbia ultimamente in una sua risposta nella Mailing List ufficiale espresso questo giudizio sull'uso delle Strutture in Gambas:

" Note that internally the structure Elements is transformed into a
temporary object pointed to the real data so that you can use the syntax
'Element.XXX'.

In other words, unless you talk to a C shared-library through the Extern
keyword, you should not use structures.

--
Benoît Minisini
"

;D

Inoltre aggiunge:

" In Gambas, a structure is a class. As soon as you use it exactly like a
class, there is no difference.


Codice: [Seleziona]
Struct MyStruct
...
End Struct

Private aStruct As MyStruct
Private aClass As MyClass

--> aClass and aStruct behave the same.

But there is something more when you use the Struct keyword in the
declaration:


Codice: [Seleziona]
' MyClass.class
Private aStruct As Struct MyStruct

Then the contents of the structure is embedded in the object where it is
declared. Consequently, to use it like another object (i.e.
MyObject.aStruct.XXX), Gambas has to create a temporary object, and so
it is slower than using a real object.

There is the same distinction with array of structures:


Codice: [Seleziona]
' MyClass.class
Private arrayOfStruct[XXX] As Struct MyStruct

arrayOfstruct[1] is slower than if the declaration has been:

Codice: [Seleziona]
Private arrayOfStruct As New MyStruct[XXX]

(note that in the late case, you have to create instances of MyStruct to
populate the array).

I hope it's a bit clearer now.

Regards,

--
Benoît Minisini
"
Titolo: Re:Comando OPEN - Aprire un file (Read e Write) in modalità RANDOM
Inserito da: sotema - 04 Ottobre 2015, 15:04:38
e se lo dice lui...
Titolo: Re:Comando OPEN - Aprire un file (Read e Write) in modalità RANDOM
Inserito da: vuott - 04 Ottobre 2015, 15:11:13
e se lo dice lui...
Mah...... la sua posizione mi pare simile a quella di T. Boege, Amministratore fra l'altro del forum tedesco dei programmatori Gambas, secondo il quale l'uso della funzione Extern va bene solo in casi limitati, dovendosi preferire la realizzazione di un apposito Componente scritto in C o C++.
Mah.... !
Titolo: Re:Comando OPEN - Aprire un file (Read e Write) in modalità RANDOM
Inserito da: sotema - 04 Ottobre 2015, 15:20:41
probabilmente la ragione sta nel garantire indipendenza da funzionalità non native del linguaggio.   :-\
Titolo: Re:Comando OPEN - Aprire un file (Read e Write) in modalità RANDOM
Inserito da: vuott - 04 Ottobre 2015, 16:04:22
...garantire indipendenza da funzionalità non native del linguaggio.
Gli proporrei in tal caso di appellarsi all'ONU o comunque alla Convenzione dell'Aja...    :rotfl:

...io sono - laddove ne ricorrano le effettive necessità - per un uso mooolto integrato dei linguaggi.  :)
Titolo: Re:Comando OPEN - Aprire un file (Read e Write) in modalità RANDOM
Inserito da: Gianluigi - 04 Ottobre 2015, 16:20:32
Scusate ragazzi,  ;D
avevo letto quanto qui riportato ma non ci ho capito molto... non ci ho capito neanche poco a dire la verità un aiutino anche a me su quanto sostiene il GranCapoLupMan?
 :ciao:

PS: Magari alla luce di quanto avevo qui postato? Please
Titolo: Re:Comando OPEN - Aprire un file (Read e Write) in modalità RANDOM
Inserito da: Gianluigi - 04 Ottobre 2015, 16:41:17
Riprendo questa discussione ed in particolare la parte relativa alle Strutture.
E' interessante come Minisini abbia ultimamente in una sua risposta nella Mailing List ufficiale espresso questo giudizio sull'uso delle Strutture in Gambas:

...
I hope it's a bit clearer now.

Regards,
Benoît Minisini


 :'(  :'(  :'(
Titolo: Re:Comando OPEN - Aprire un file (Read e Write) in modalità RANDOM
Inserito da: vuott - 04 Ottobre 2015, 16:53:45
Mah.... guarda.... la sostanza sta tutta qua:

" In other words, unless you talk to a C shared-library through the Extern
keyword, you should not use structures.
"

In effetti, come ha ben intuito sotema, Minisini (ma anche altri, come ho riportato) ritiene sia più opportuno utilizzare le risorse più propriamente native del linguaggio Gambas.
Lui non può, però, negare la concessione di un uso delle Strutture (più proprie del C ) nei casi di gestione di librerie esterne. Infatti - come in modo un po' forte ti risposi in questa discussione - passare a funzioni esterne scritte in C una risorsa come un array di tipo Variant, significa non conoscere i sorgenti (....scritti in C  :D fra l'altro !) del linguaggio Gambas.

La Struttura del linguaggio C, in fondo, è un elemento semplice, un'area di memoria riservata, nella quale si allineano uno dopo l'altro vari membri in base al loro tipo di dato. Il problema gigantesco (questo sì che è un "problema" di Gambas) è che Gambas non riesce - o meglio, non sempre, non in tutti i casi riesce - a gestire precisamente le Strutture passate o da passare ad una funzione esterna scritta in C.   Questa è una delle ragioni principali per la quale Tobias Boege ritiene opportuno creare in tali casi un apposito Componente di Gambas scritto in C.... io però appartengo ad un'altra scuola di pensiero, secondo la quale devi essere tu programmatore in questi casi difficili a conciliare in qualche modo tutto e a calcolare gli esatti allineamenti e compensazioni.
Su questo argomento ho abbozzato questi due mattoni micidiali:  (http://forum.ubuntu-it.org/images/smilies/stars.gif)
http://www.gambas-it.org/wiki/index.php?title=Gestire_con_sicurezza_le_Strutture_esterne
http://www.gambas-it.org/wiki/index.php?title=Gestire_con_un_Puntatore_le_Strutture_esterne

In Gambas il suo Variant è definito da un paio di Strutture:
Codice: [Seleziona]
/* Gambas VARIANT datatype definition */

typedef
  struct {
    GB_TYPE type;
union {
char _boolean;
unsigned char _byte;
short _short;
int _integer;
int64_t _long;
float _single;
double _float;
GB_DATE_VALUE _date;
char *_string;
intptr_t _pointer;
void *_object;
int64_t data;
}
value;
}
PACKED
  GB_VARIANT_VALUE;

typedef
  struct {
    GB_TYPE type;
GB_VARIANT_VALUE value;
#if __WORDSIZE == 64
int64_t _pad;
#endif
    }
  GB_VARIANT;
   
comprensibili solo da gambas.
Titolo: Re:Comando OPEN - Aprire un file (Read e Write) in modalità RANDOM
Inserito da: Gianluigi - 04 Ottobre 2015, 20:18:51
Ti ringrazio molto delle spiegazioni, quindi praticamente... avevo ragione io  :P  :rotfl:
 ;D ;D ;D
 :ciao:
Titolo: Re:Comando OPEN - Aprire un file (Read e Write) in modalità RANDOM
Inserito da: vuott - 04 Ottobre 2015, 20:47:11
quindi praticamente... avevo ragione io 

Diciamo che... sei un Minisiano.

Io appartengo ad un'altra corrente di pensiero.    ;D
Titolo: Re:Comando OPEN - Aprire un file (Read e Write) in modalità RANDOM
Inserito da: Gianluigi - 04 Ottobre 2015, 20:56:37
quindi praticamente... avevo ragione io 

Diciamo che... sei un Minisiano.

Io appartengo ad un'altra corrente di pensiero.    ;D

Si lo so, ma fra Minisiano e Sanmidiano c'è una certa assonanza (musicale).
 :ciao:
Titolo: Re:Comando OPEN - Aprire un file (Read e Write) in modalità RANDOM
Inserito da: vuott - 04 Ottobre 2015, 21:06:53
Si lo so, ma fra Minisiano e Sanmidiano c'è una certa assonanza (musicale).

Questa è una posizione del tutto eretica !    >:(