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

Offline Jack_Gamb

  • Gamberetto
  • *
  • Post: 1
    • Mostra profilo
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.    :)

Offline pastrank

  • Maestro Gambero
  • ****
  • Post: 265
    • Mostra profilo
Re: Comando OPEN - Aprire un file (Read e Write) in modalità RANDOM
« Risposta #1 il: 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 ti puo' essere utile (intendo l'uso di seek: ovvero, calcoli la posizione dove scrivere, e la' scrivi).
« Ultima modifica: 11 Febbraio 2015, 22:37:22 da pastrank »

Offline vuott

  • Moderatore globale
  • Senatore Gambero
  • *****
  • Post: 11.307
  • Ne mors quidem nos iunget
    • Mostra profilo
Re: Comando OPEN - Aprire un file (Read e Write) in modalità RANDOM
« Risposta #2 il: 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
« Chiunque, non ricorrendo lo stato di necessità, nel proprio progetto Gambas fa uso delle istruzioni Shell o Exec, è punito con la sanzione pecuniaria da euro 20,00 a euro 60,00. »

Offline Top Fuel

  • Gran Maestro dei Gamberi
  • *****
  • Post: 960
    • Mostra profilo
Re: Comando OPEN - Aprire un file (Read e Write) in modalità RANDOM
« Risposta #3 il: 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.
Dear youtube administrators, your search bar is broken. When I type the letter "J" it appears justin bieber when it should appear Jimi Hendrix. Fix this, please.

Offline Gianluigi

  • Moderatore globale
  • Senatore Gambero
  • *****
  • Post: 4.158
  • Tonno verde
    • Mostra profilo
Re: Comando OPEN - Aprire un file (Read e Write) in modalità RANDOM
« Risposta #4 il: 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.
nuoto in attesa del bacio di una principessa che mi trasformi in un gambero azzurro

Offline vuott

  • Moderatore globale
  • Senatore Gambero
  • *****
  • Post: 11.307
  • Ne mors quidem nos iunget
    • Mostra profilo
Re: Comando OPEN - Aprire un file (Read e Write) in modalità RANDOM
« Risposta #5 il: 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
« Ultima modifica: 13 Febbraio 2015, 00:55:15 da vuott »
« Chiunque, non ricorrendo lo stato di necessità, nel proprio progetto Gambas fa uso delle istruzioni Shell o Exec, è punito con la sanzione pecuniaria da euro 20,00 a euro 60,00. »

Offline Gianluigi

  • Moderatore globale
  • Senatore Gambero
  • *****
  • Post: 4.158
  • Tonno verde
    • Mostra profilo
Re: Comando OPEN - Aprire un file (Read e Write) in modalità RANDOM
« Risposta #6 il: 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:
nuoto in attesa del bacio di una principessa che mi trasformi in un gambero azzurro

Offline vuott

  • Moderatore globale
  • Senatore Gambero
  • *****
  • Post: 11.307
  • Ne mors quidem nos iunget
    • Mostra profilo
Re: Comando OPEN - Aprire un file (Read e Write) in modalità RANDOM
« Risposta #7 il: 13 Febbraio 2015, 10:00:45 »
In vero, aveva già dato la soluzione l'amico pastrank suggerendo l'uso della funzione Seek .
« Ultima modifica: 04 Novembre 2022, 16:54:01 da vuott »
« Chiunque, non ricorrendo lo stato di necessità, nel proprio progetto Gambas fa uso delle istruzioni Shell o Exec, è punito con la sanzione pecuniaria da euro 20,00 a euro 60,00. »

Offline Top Fuel

  • Gran Maestro dei Gamberi
  • *****
  • Post: 960
    • Mostra profilo
Re: Comando OPEN - Aprire un file (Read e Write) in modalità RANDOM
« Risposta #8 il: 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?
Dear youtube administrators, your search bar is broken. When I type the letter "J" it appears justin bieber when it should appear Jimi Hendrix. Fix this, please.

Offline Gianluigi

  • Moderatore globale
  • Senatore Gambero
  • *****
  • Post: 4.158
  • Tonno verde
    • Mostra profilo
Re: Comando OPEN - Aprire un file (Read e Write) in modalità RANDOM
« Risposta #9 il: 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:
nuoto in attesa del bacio di una principessa che mi trasformi in un gambero azzurro

Offline Gianluigi

  • Moderatore globale
  • Senatore Gambero
  • *****
  • Post: 4.158
  • Tonno verde
    • Mostra profilo
Re: Comando OPEN - Aprire un file (Read e Write) in modalità RANDOM
« Risposta #10 il: 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:
nuoto in attesa del bacio di una principessa che mi trasformi in un gambero azzurro

Offline Top Fuel

  • Gran Maestro dei Gamberi
  • *****
  • Post: 960
    • Mostra profilo
Re: Comando OPEN - Aprire un file (Read e Write) in modalità RANDOM
« Risposta #11 il: 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. :)
Dear youtube administrators, your search bar is broken. When I type the letter "J" it appears justin bieber when it should appear Jimi Hendrix. Fix this, please.

Offline vuott

  • Moderatore globale
  • Senatore Gambero
  • *****
  • Post: 11.307
  • Ne mors quidem nos iunget
    • Mostra profilo
Re: Comando OPEN - Aprire un file (Read e Write) in modalità RANDOM
« Risposta #12 il: 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, 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
« Chiunque, non ricorrendo lo stato di necessità, nel proprio progetto Gambas fa uso delle istruzioni Shell o Exec, è punito con la sanzione pecuniaria da euro 20,00 a euro 60,00. »

Offline Top Fuel

  • Gran Maestro dei Gamberi
  • *****
  • Post: 960
    • Mostra profilo
Re: Comando OPEN - Aprire un file (Read e Write) in modalità RANDOM
« Risposta #13 il: 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.
Dear youtube administrators, your search bar is broken. When I type the letter "J" it appears justin bieber when it should appear Jimi Hendrix. Fix this, please.

Offline vuott

  • Moderatore globale
  • Senatore Gambero
  • *****
  • Post: 11.307
  • Ne mors quidem nos iunget
    • Mostra profilo
Re: Comando OPEN - Aprire un file (Read e Write) in modalità RANDOM
« Risposta #14 il: 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
« Chiunque, non ricorrendo lo stato di necessità, nel proprio progetto Gambas fa uso delle istruzioni Shell o Exec, è punito con la sanzione pecuniaria da euro 20,00 a euro 60,00. »