Autore Topic: utilizzo di stream di lunghezza fissa  (Letto 1201 volte)

Offline giob1642

  • Grande Gambero
  • ***
  • Post: 159
    • Mostra profilo
utilizzo di stream di lunghezza fissa
« il: 02 Novembre 2013, 21:24:35 »
 Al di la delle implicazioni in vari database (mysql,sqlite.......),suponiamo d'avere una struttura dati variabile , ma di lunghezza totale fissa, che voglio memorizzare in un file testo (text edit,text area ) per es:
record . uno
         campo 1   nome        len 25         
         campo 2   cognome   len 35
         campo 3    età           len 12
         campo 4    sesso       len 1
                          totale        len 73
record . due
         campo 1   nome        len 25         
         campo 2   cognome   len 35
         campo 3    laureato    len 1
         campo 4      vuoti       len 11
                          totale        len 73
record .tre(come uno)
         campo 1   nome        len 25         
         campo 2   cognome   len 35
         campo 3    età           len 12
         campo 4    sesso       len 1
                          totale        len 73
record . quattro (come uno)
         campo 1   nome        len 25         
         campo 2   cognome   len 35
         campo 3    età           len 12
         campo 4    sesso       len 1
                          totale        len 73

potrei usare:
DIM hFile AS File
DIM sLine AS String

hFile = OPEN "pippo" FOR INPUT
............................
  LINE INPUT #hFile, sLine
................................
e quindi consideralo un file text sequenzizle  e leggerlo con seek..........................

Esiste un modo per assegnare a sLine una lunghezza fissa  e quindi muoversi di conseguenza
per es  far partire, e solo in fase di lettura, il secondo record da seek 73+25 con tutti quello che ciò comporta o devo ricorrere sempre ad un record con spazi vuoti ?
grazie giorgio




Offline Top Fuel

  • Gran Maestro dei Gamberi
  • *****
  • Post: 960
    • Mostra profilo
Re: utilizzo di stream di lunghezza fissa
« Risposta #1 il: 04 Novembre 2013, 12:13:22 »
Se ho capito bene tu vorresti posizionare quanto letto dal file in una posizione specifica all'interno della stringa, giusto?
In ogni caso le stringhe a lunghezza fissa in Gambas non esistono.
« Ultima modifica: 04 Novembre 2013, 12:14:55 da Top Fuel »
Dear youtube administrators, your search bar is broken. When I type the letter "J" it appears justin bieber when it should appear Jimi Hendrix. Fix this, please.

Offline giob1642

  • Grande Gambero
  • ***
  • Post: 159
    • Mostra profilo
Re: utilizzo di stream di lunghezza fissa
« Risposta #2 il: 06 Novembre 2013, 17:24:55 »
Cerco di spiegare quello che sto tentando di fare  che va visto in un discorso ben più complesso:
Supponiamo d'avere una serie   di record di tre dati primo,secondo e terzo i singoli dati dei vari record ovviamente possono avere lunghezze diverse,
per es. il  primo dato può essere: Giovanni
                                                      Mario
                                                      Ferdinando
 volendo ottimizzare e velocizzare l'estrazione della prima colonna, la cosa più semplice è rendere tutti dati di lunghezza fissa, per es aggiungendo degli spazi vuoti ed operando con seek.
Ciò e senza dubbio possibile, anzi  utilizzando gli stream che accettano la lunghezza fissa, è estremamente semplice; mi chiedevo se c'è un modo , visto che utilizzo  "," come separatore, se è possibile evitare d'inserire spazi vuoti.

Al momento trovo anche un altra difficoltà, non so se è un bug od un mio errore   l'accenno brevemente  sperando che possa aiutarmi.

Public Sub Form_Open()
1-Dim hfile As File
2-Dim mypath, myfile As String

 3- myfile = "Begin.txt"                                'file creato nella riga successiva ed attualmente vuoto

 4-hfile = Open myfile For Write Create     'questa riga da errore "access forbiden" e non capisco perché
                                                                    ' visto che i permessi sono giusti
 5-  Shell "pwd" |./myfile
 6-Close Hfile

'  Line Input #File.In, mypath
'  Line Input #File.out, mypath
' Print mypath

   '  While Not mypath
   '    Line Input #File.Out, mypath
   '    textarea1.text = mypath
   ' ' TextBox8.Text = mypath
   '  Wend
End

grazie giorgio

Offline vuott

  • Moderatore globale
  • Senatore Gambero
  • *****
  • Post: 11.608
  • Ne mors quidem nos iunget
    • Mostra profilo
Re: utilizzo di stream di lunghezza fissa
« Risposta #3 il: 06 Novembre 2013, 18:07:02 »
2-Dim mypath, myfile As String

 3- myfile = "Begin.txt"                                'file creato nella riga successiva ed attualmente vuoto

 4-hfile = Open myfile For Write Create     'questa riga da errore "access forbiden" e non capisco perché
                                                                    ' visto che i permessi sono giusti

Siamo sicuri che il solo nome del file ("Begin.txt") sia sufficiente per poter individuare il file medesimo ?   :-X
Sembrerebbe monco dell'intero percorso ove il file è posizionato.  :-\
« 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 giob1642

  • Grande Gambero
  • ***
  • Post: 159
    • Mostra profilo
Re: utilizzo di stream di lunghezza fissa
« Risposta #4 il: 06 Novembre 2013, 20:45:28 »
si è giusto in quanto è un file creato  per permettere alla istruzione successiva di scrivere l'output del comando schell nel rispettivo file input (vd pipe) permettendo a gambas di assegnarlo a mypath
grazie

Offline Top Fuel

  • Gran Maestro dei Gamberi
  • *****
  • Post: 960
    • Mostra profilo
Re: utilizzo di stream di lunghezza fissa
« Risposta #5 il: 07 Novembre 2013, 00:33:46 »
Ciò e senza dubbio possibile, anzi  utilizzando gli stream che accettano la lunghezza fissa, è estremamente semplice; mi chiedevo se c'è un modo , visto che utilizzo  "," come separatore, se è possibile evitare d'inserire spazi vuoti.

Ci ho pensato su un pò ma non vedo altre soluzioni. D'altronde se esistessero le stringhe a lughezza fissa i caratteri in eccesso sarebbero comunque riempiti con spazi.
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 giob1642

  • Grande Gambero
  • ***
  • Post: 159
    • Mostra profilo
Re: utilizzo di stream di lunghezza fissa
« Risposta #6 il: 07 Novembre 2013, 14:35:25 »
ed è proprio questo che vorrei sapere ; se lo stream d'imput è di lunghezza fissa gli spazi vuoti vengono aggiunti automaticamente o no?
giorgio
 

Offline vuott

  • Moderatore globale
  • Senatore Gambero
  • *****
  • Post: 11.608
  • Ne mors quidem nos iunget
    • Mostra profilo
Re: utilizzo di stream di lunghezza fissa
« Risposta #7 il: 07 Novembre 2013, 17:01:56 »
LINE INPUT legge il flusso di testo sino al primo dato avente valore x0A (Line feed character).

Ponendo la funzione Seek, si va a leggere dal byte puntato da Seek sino al primo dato avente valore x0A.
In questo senso la fissità della quantità di byte letti è posta, sulla base ovviamente della lunghezza di ciascuna riga, dal byte avente valore x0A.


Una modalità per leggere in modo fisso (...nel senso un numero fisso di dati per volta) un flusso, ma senza l'influenza (come invece visto prima) del carattere non stampabile x0A, è la seguente:
Codice: gambas [Seleziona]
Read #fluxus, s, n


laddove n è la quantità di byte, partendo dal numero 0 (ossia dal 1° byte del flusso), che si vogliono leggere. Ovviamente, se si intende cominciare a leggere da un byte diverso dal primo, si utilizzerà la predetta funzione Seek .
« 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 giob1642

  • Grande Gambero
  • ***
  • Post: 159
    • Mostra profilo
Re: utilizzo di stream di lunghezza fissa
« Risposta #8 il: 08 Novembre 2013, 12:54:46 »
quanto dici vuot è giusto ma come ci si deve comportare nell'inserimento dati? Bisogna riempire campi o parte di essi con spazi vuoti o basta un  semplice separatore?
giorgio

Offline vuott

  • Moderatore globale
  • Senatore Gambero
  • *****
  • Post: 11.608
  • Ne mors quidem nos iunget
    • Mostra profilo
Re: utilizzo di stream di lunghezza fissa
« Risposta #9 il: 08 Novembre 2013, 14:02:15 »
Ricordo a me stesso nuovamente che l'istruzione Line Input legge un file come testo.


Riguardo alla scrittura in Gambas di file a lunghezza fissa, questa in vero è possibile - aggiungendo un terzo elemento all'istruzione Write che specifichi, appunto, quanto lunga deve essere comunque quella scrittura nel file
Esempio:
Codice: gambas [Seleziona]

  Write #fluxus, "abcd", 10

laddove la quantità di dati passati da scrivere è pari a quattro (ossia: a-b-c-d), ma si impone all'istruzione comunque di scriverne 10. I restanti sei saranno scritti ciascuno automaticamente come valore zero.

Questa soluzione, come è evidente, non genera le righe all'interno del file. Perciò, volendola comunque utilizzare, si dovrà trovare una soluzione per aggiungere a quei 10 dati un undicesimo: il famoso carattere non stampabile x0A.
« Ultima modifica: 14 Novembre 2013, 23:52:50 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 Picavbg

  • Senatore Gambero
  • ******
  • Post: 1.620
    • Mostra profilo
Re: utilizzo di stream di lunghezza fissa
« Risposta #10 il: 14 Novembre 2013, 23:49:27 »
Cerco di spiegare quello che sto tentando di fare  che va visto in un discorso ben più complesso:
Supponiamo d'avere una serie   di record di tre dati primo,secondo e terzo i singoli dati dei vari record ovviamente possono avere lunghezze diverse,
per es. il  primo dato può essere: Giovanni
                                                      Mario
                                                      Ferdinando
 volendo ottimizzare e velocizzare l'estrazione della prima colonna, la cosa più semplice è rendere tutti dati di lunghezza fissa, per es aggiungendo degli spazi vuoti ed operando con seek.
Ciò e senza dubbio possibile, anzi  utilizzando gli stream che accettano la lunghezza fissa, è estremamente semplice; mi chiedevo se c'è un modo , visto che utilizzo  "," come separatore, se è possibile evitare d'inserire spazi vuoti.

Sto leggendo solo ora questa discussione e se fossi in te, semprecchè non abbia già risolto il problema, trascurerei il coneccto della lunghezza fissa. Aggiungerei in registrazione un carattere separatore come "~", per es., fra i tre dati del tuo esempio. Aprendo successivamente il file.txt in lettura eseguirei uno split  della stringa letta in un array unidimensionale. Infine potrei trasferire il contenuto dell'array, elemento dopo elemento in tre stringhe diverse.
Naturalmente tutto ciò dipende sempre da che cosa vuoi ottenere.
Se l'idea ti va, possiamo approfondire il concetto scrivendo anche il codice necessario.
 :ciao:
:ciao:

Offline giob1642

  • Grande Gambero
  • ***
  • Post: 159
    • Mostra profilo
Re: utilizzo di stream di lunghezza fissa
« Risposta #11 il: 25 Novembre 2013, 12:08:06 »
Grazie per l'invito di sviluppare del codice insieme.
Cerco di spiegarti quello che sto cercando di fare: mi trovo a sviluppare un prog che usa database con    tabelle che contiene colonne con milioni e milioni di righe, per es. ciò capita se si sta lavorando sui vari genomi o su studi di processi; in tal caso mysql od altri database relazionali diventano lenti ed inefficienti.
 Per ovviare a tali inconvenienti  devi indirizzarti su nuove tecnologie quali per es. nosql, costruirti un tuo motore di database od usufruire delle non poche esperienze già fatte in merito.
Proseguendo su questa via ho costruito una tabella (che riporto i un file.txt) con campi di lunghezza fissa, in essa è agevole individuare campi e/o colonne con seek .......................; quello che cercavo di sapere con la mia domanda è: premesso che   posso ottenere tale risultato o inserendo nei  vari campi   dati ovviamente disuguali  costretti ad essere di lunghezza uguale  aggiungendoci degli spazi  vuoti  od inserendo un elemento di separazione, pur mantenendo lo stream collegato al file di  lunghezza fissa.
In tal  caso qual'è la routine in lettura più efficiente ossia  qual'è la via migliore in termini di tempo, c'è qualc'uno  che ha fatto esperienze in merito
giorgio



Offline vuott

  • Moderatore globale
  • Senatore Gambero
  • *****
  • Post: 11.608
  • Ne mors quidem nos iunget
    • Mostra profilo
Re: utilizzo di stream di lunghezza fissa
« Risposta #12 il: 25 Novembre 2013, 12:39:01 »
In tal  caso qual'è la routine in lettura più efficiente ossia  qual'è la via migliore in termini di tempo, c'è qualc'uno  che ha fatto esperienze in merito

Rimando al test che ho effettuato sul mio calcolatore:
http://www.gambas-it.org/smf/index.php?topic=3088.msg31101#msg31101

Resterebbe da testare anche la modalità Line Input .
« 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 Picavbg

  • Senatore Gambero
  • ******
  • Post: 1.620
    • Mostra profilo
Re: utilizzo di stream di lunghezza fissa
« Risposta #13 il: 25 Novembre 2013, 22:46:06 »
ho costruito una tabella (che riporto i un file.txt) con campi di lunghezza fissa, in essa è agevole individuare campi e/o colonne con seek .......................;
Non ho trovato il file che hai indicato come allegato, tuttavia, visto che i file di cui parli sono molto voluminosi, la gestione tramite file.txt non credo sia agevole; sempre meglio un DB. che puoi aggiornare con inserimenti, modifiche e cancellazione di righe tabellari, senza dovere ogni volta riscrivere tutto il file.txt., anche per una sola operazione fra quelle sopra indicate.
Comunque, nella documentazione presente in gambasdoc.org, attraverso l'indice del linguaggio, cliccando sull'istruzione seek, si apre la pagina relativa, attraverso la quale puoi accedere a tutte le "Funzioni di Stream e Input/Output" con le varie possibilità d'accesso ai file.txt.
Con una gestione di detto tipo la scrittura di record a lunghezza fissa certamente permette di muoversi agevolmente da un record ad un altro, tramite il fattore di moltiplicazione agganciato alla lunghezza record. Occorrerà però avere sempre chiara la posizione del record da trattare all'interno del file.
La velocità è sempre determinata dall'ampiezza del file. Io ho pochissima esperienza sui file.txt e non ho mai usato l'istruzione seek. Credo che un DB relazionale, possibilmente indicizzato sulla "Primary Key", debba fare meglio al caso tuo. Purtroppo, in Gambas, se il tuo DB fosse esclusivamente locale, l'unica struttura conciliabile è quella di tipo SQLite3.
Qualsiasi strada tu volessi intraprendere è sempre da provare. Prima di gettare alle ortiche un'organizzazione tipo DB, potresti provare anche quella e decidere successivamente per il meglio.
 :ciao:
:ciao:

Offline Picavbg

  • Senatore Gambero
  • ******
  • Post: 1.620
    • Mostra profilo
Re: utilizzo di stream di lunghezza fissa
« Risposta #14 il: 11 Luglio 2014, 19:57:27 »
Riprendo questa discussione perchè oggi ho dovuto affrontare un problema rivolto alla registrazione e lettura di file .txt contenenti record di natura mista e quindi di lunghezza variabile, sia nel numero dei campi componenti ciascun record, sia nel numero di caratteri complessivi presenti in ciascun record.
Il mio problema è diverso fondamentalmente dall'oggetto indicato in questa discussione, ma reputo che possa essere impiegato anche per le necessità indicate nel primo post.

Io posso dover registrare record formati, da 12 campi, da 8 campi, da 7 campi e da 10 campi. Ho visto che, leggendo il file con l'istruzione "Line Input",  posso impegnare un unica stringa contenente tutti i caratteri dell'ultimo record letto. Ciascun campo è diviso dal suo successivo, per default, da un carattere di tabulazione ("\t"). Allora, attraverso l'istruzione split, posso trasferire il contenuto della stringa fornita dalla lettura del file in un array definito con le dimensioni massime possibili, cioè 12. Dopo tale trasferimento di dati, posso riconoscere il tipo record letto (nel mio caso ho registrato un campo con il tipo record), ma potrei farlo anche riconoscendo  il numero degli elementi valorizzati tramite l'istruzione  split.
Ora il trattamento dei dati letti diventa assolutamente semplice.
Ecco le istruzioni utilizzate:
Codice: gambas [Seleziona]
Dim hRec As String
Dim $CampiRec As New String[15]
'----------------------------------------------------------------------
  If Not Exist($File) Then
       hFilSeq = Open $File For Create              'Apre il file da creare
  Else
    hFilSeq = Open $File For Input                   'Apre il file per la lettura dell'ultimo record
    While Not Eof(hFilSeq)
      Line Input #hFilSeq, hRec
      $CampiRec = Split(hRec, "\t")
---- bla ---- bla ---- ba----
   Wend


 :ciao:
:ciao: