Autore Topic: [risolto]Trattamento file .txt con record a lunghezza variabile  (Letto 1215 volte)

Offline Picavbg

  • Senatore Gambero
  • ******
  • Post: 1.620
    • Mostra profilo
Vorrei aggiungere al mio programma un ulteriore livello di sicurezza sui dati contenuti nel DB-SQLite3 che ho in costruzione. Nel gestore DB (Sqliteman) ho notato ed utilizzato la funzione "Dump Database". Detta funzione crea un unico file in formato .txt di tutto il DB, dalle impostazioni alle tabelle coi loro dati. Solo che  che il file che ne viene fuori si presenta così:
Citazione
PRAGMA foreign_keys=OFF;
BEGIN TRANSACTION;
CREATE TABLE 'RacCodVoci'  ( 'NumVoCassa' INTEGER, 'NumVoColleg' INTEGER,  PRIMARY KEY ( 'NumVoCassa') );
CREATE TABLE 'Movimgg'  ( 'DtMovvgg' INTEGER, 'OraMovvgg' INTEGER, 'NuProMovvgg' BYTE DEFAULT NULL, 'CoVocMovvgg' INTEGER DEFAULT NULL, 'DescrMovvgg' VARCHAR(100) DEFAULT NULL, 'MonMovvgg' CHAR(1) DEFAULT NULL, 'ImpMovvgg' FLOAT DEFAULT NULL, 'BenefMovvgg' CHAR(1) DEFAULT NULL,  PRIMARY KEY ( 'DtMovvgg', 'OraMovvgg') );
CREATE TABLE 'RestaCassagg'  ( 'DtCassagg' INTEGER, 'CoVoResCasgg' INTEGER, 'ValCasgg' CHAR(1) DEFAULT NULL, 'ImpCasgg' FLOAT DEFAULT NULL, PRIMARY KEY ( 'DtCassagg', 'CoVoResCasgg') );
...............................................................................
INSERT INTO "CausaliFreq" VALUES('bar',20090525);
INSERT INTO "CausaliFreq" VALUES('fotografie per tessera mia',20090409);
CREATE TABLE 'PianCont'  ( 'NumVoce'  PRIMARY KEY, 'NomeVoce' VARCHAR(50) DEFAULT NULL, 'ContrPartSiNo' CHAR(1) DEFAULT NULL, 'DtPrimoUso' INTEGER DEFAULT NULL );
INSERT INTO "PianCont" VALUES(10000000,'ATTIVO','N',NULL);
INSERT INTO "PianCont" VALUES(10100000,'CASSA','N',NULL);
INSERT INTO "CausaliFreq" VALUES('bar',20090525);
INSERT INTO "CausaliFreq" VALUES('fotografie per tessera mia',20090409);
CREATE TABLE 'PianCont'  ( 'NumVoce'  PRIMARY KEY, 'NomeVoce' VARCHAR(50) DEFAULT NULL, 'ContrPartSiNo' CHAR(1) DEFAULT NULL, 'DtPrimoUso' INTEGER DEFAULT NULL );
INSERT INTO "PianCont" VALUES(10000000,'ATTIVO','N',NULL);
INSERT INTO "PianCont" VALUES(10100000,'CASSA','N',NULL);
...............................................................................
INSERT INTO "PianCont" VALUES('00000000','Record Flag nuovi inserimenti','S','NULL');
INSERT INTO "PianCont" VALUES(NULL,'NULL','NULL','NULL');
COMMIT;

Ogni record è diverso dall'altro, come lunghezza ed ovviamente come contenuto, ma tutti finiscono col ";".

Da ieri cerco una formula per la lettura di tutto il record, a prescindere dalla sua lunghezza, ma non ho ancora scoperto come fare. Nel programma ho inserito le seguenti istruzioni:
Codice: [Seleziona]
PRIVATE h_File AS File
PRIVATE $_Eof AS String
PRIVATE $_File AS String
PRIVATE $_Rec AS String

PUBLIC SUB _new()
..............................................
OPEN $_File FOR READ AS #h_File    
...........................................
SELECT CASE ModuliVari.$_FlgNmTab
    CASE "piancont"
          ME.Popolapiancont
 END SELECT  
END

PUBLIC SUB Popolapiancont()
DIM i_PoStri AS Integer

 DO UNTIL $_Eof = "FiFi"
    ME.Leggi_FlTabSeq
i_PoStri = InStr($_Rec, "piancont")
    IF i_PoStri <> 0 THEN
...................................................
    ENDIF
  LOOP
END

PUBLIC SUB Leggi_FlTabSeq()
    READ #h_File, $_Rec, -512
     IF Eof(h_File) THEN
        $_Eof = "FiFi"
    ENDIF
END
l'istruzione READ così com'è impostata legge sempre 512 byte, per cui  se il record è più lungo, viene troncato al 512° crt, se invece è più corto, vengono compresi nei 512 crt anche i successivi, pur essendo appartenenti a uno o più record seguenti.

Come posso fermare la mia lettura al solo record effettivo, ciè quello compreso fra un ";"  ed il ";" successivo?
 ::)
Ciao.
« Ultima modifica: 02 Febbraio 2010, 11:26:02 da Picavbg »
:ciao:

Offline Ceskho

  • Amministratore
  • Senatore Gambero
  • *****
  • Post: 3.778
  • Vi Veri Veniversum Vivus Vici
    • Mostra profilo
    • Pagina Personale
Re: Trattamento file .txt con record a lunghezza variabile
« Risposta #1 il: 28 Gennaio 2010, 17:36:03 »
Ti aiuto giusto poco poco perchè mi hai trattato male nel precedente post insultabndo i servizi segreti.. :P

Hai pensato ad usare split tenendo il carattere ; come identificatore?

Offline fsurfing

  • Moderatore
  • Senatore Gambero
  • *****
  • Post: 2.482
    • Mostra profilo
Re: Trattamento file .txt con record a lunghezza variabile
« Risposta #2 il: 28 Gennaio 2010, 18:22:20 »
si la miglior cosa è caricare il file in una stringa con file.load( percorso)

poi ottenere un array con tutte le righe con

Codice: [Seleziona]
nomearray=split(stringa,";")

così nell' array avrai una riga per ogni indice
« Ultima modifica: 28 Gennaio 2010, 18:26:11 da fsurfing »

Offline Ceskho

  • Amministratore
  • Senatore Gambero
  • *****
  • Post: 3.778
  • Vi Veri Veniversum Vivus Vici
    • Mostra profilo
    • Pagina Personale
Re: Trattamento file .txt con record a lunghezza variabile
« Risposta #3 il: 28 Gennaio 2010, 18:24:11 »
Sei il solito guasta feste  >:(

Offline Picavbg

  • Senatore Gambero
  • ******
  • Post: 1.620
    • Mostra profilo
Re: Trattamento file .txt con record a lunghezza variabile
« Risposta #4 il: 28 Gennaio 2010, 18:50:36 »
Capisco che entrambi citate lo stesso metodo di acquisizione dati, ma l'istruzione file.load(percorso)  :o carica tutto il file di Dump-DB dentro una stringa in un colpo solo, almeno così ho capito, impegnando così milioni di byte. :o   Anche se assai pratico, di contro, mi pare alquanto dispendioso in termini di memoria impegnata. Non ho mai usato le istruzioni che mi avete suggerito, ma in assenza di altre soluzioni, diventa, dal punto di vista del programmatore, quella meno indolore....Proverò. Grazie.
Ciao a tutti.
:ciao:

Offline Ceskho

  • Amministratore
  • Senatore Gambero
  • *****
  • Post: 3.778
  • Vi Veri Veniversum Vivus Vici
    • Mostra profilo
    • Pagina Personale
Re: Trattamento file .txt con record a lunghezza variabile
« Risposta #5 il: 28 Gennaio 2010, 18:51:47 »
Potresti caricare diverse righe alla volta...è pur sempre un file di testo...

Offline dex

  • Gran Maestro dei Gamberi
  • *****
  • Post: 872
    • Mostra profilo
Re: Trattamento file .txt con record a lunghezza variabile
« Risposta #6 il: 28 Gennaio 2010, 19:02:23 »
Capisco che entrambi citate lo stesso metodo di acquisizione dati, ma l'istruzione file.load(percorso)  :o carica tutto il file di Dump-DB dentro una stringa in un colpo solo, almeno così ho capito, impegnando così milioni di byte. :o   Anche se assai pratico, di contro, mi pare alquanto dispendioso in termini di memoria impegnata. Non ho mai usato le istruzioni che mi avete suggerito, ma in assenza di altre soluzioni, diventa, dal punto di vista del programmatore, quella meno indolore....Proverò. Grazie.
Ciao a tutti.

sqlite si mantiene molto basso nelle dimensioni del database, nel mio progetto ho effettuato una simulazione facendo caricare oltre 10.000 record, il file finale era poco più grande di un mb, con i pc odierni tenere in memoria un mb è nulla per le risorse.

piuttosto non so quanto si può caricare una variabile sia in termini di dimensioni che con le lunghezze delle stringhe.

Offline fsurfing

  • Moderatore
  • Senatore Gambero
  • *****
  • Post: 2.482
    • Mostra profilo
Re: Trattamento file .txt con record a lunghezza variabile
« Risposta #7 il: 28 Gennaio 2010, 19:36:21 »
Citazione
iuttosto non so quanto si può caricare una variabile sia in termini di dimensioni che con le lunghezze delle stringhe.
quello non è certo un problema, io su alcune prove ho caricato libri interi e lavorato con array di 10000 linee

Offline Picavbg

  • Senatore Gambero
  • ******
  • Post: 1.620
    • Mostra profilo
Re: Trattamento file .txt con record a lunghezza variabile
« Risposta #8 il: 31 Gennaio 2010, 00:00:43 »
la ... Split è veramente una bomba. Non la conoscevo. Ho ottenuto quello che desideravo. Ho frazionato prima il file nei record che lo compongo, poi dai record, sempre con lo stesso procedimento ho estratto i campi, escludendo tutti i caratteri superflui. Ancora non ho finito, perchè mi sono applicato solo su un tipo-record, però il risultato è splendido e posso proseguire col vento in poppa.
Grazie a tutti.
 ;D ;D ;D
Ciao.
:ciao:

Offline Ceskho

  • Amministratore
  • Senatore Gambero
  • *****
  • Post: 3.778
  • Vi Veri Veniversum Vivus Vici
    • Mostra profilo
    • Pagina Personale
Re: Trattamento file .txt con record a lunghezza variabile
« Risposta #9 il: 31 Gennaio 2010, 01:01:39 »
Quando avrai risolto potresti scrivere il codice qui e poi porre [RISOLTO] nel titolo...:-)

Offline Picavbg

  • Senatore Gambero
  • ******
  • Post: 1.620
    • Mostra profilo
Re: Trattamento file .txt con record a lunghezza variabile
« Risposta #10 il: 01 Febbraio 2010, 23:14:02 »
Pensavo di di utilizzare una parte del codice trattato in questa discussione per approcciare un articolo per Openzine, ma non mi sembra di essere riuscito feicemente nell'impresa. Allora, visto che ho superato con ampia soddisfazione l'ostacolo che avevo incontrato, grazie al vostro aiuto, preferisco chiudere intanto questa discussione e sono ben lieto di riportare qui il codice scritto nel mio programma. Chiedo scusa per la denominazione di campi e variabili, ma è un difetto che mi riporto dietro da tanti anni, ma che però mi permette facilmente di risalire al loro contenuto. In definitiva è un metodo di dichiarazione "parlante", ottenuto riunendo in un'unica parola le abbreviazioni delle descrizioni dei vari oggetti.
Codice: [Seleziona]
PUBLIC SUB Leggi_FlTabSeq()

PRIVATE $_File AS String
PRIVATE $_Rec AS String
PRIVATE $_RgFl AS NEW String[]
PRIVATE $_RgRecDB AS NEW String[]     

PRIVATE i_IndRg AS Integer
PRIVATE i_TotLetti AS Integer

PRIVATE RecTab AS Result

$_Rec = File.Load($_File)
$_RgFl = Split($_Rec, ";")
  i_IndMax = $_RgFl.Count - 1
  FOR i = 0 TO i_IndMax
    b_Esito = $_RgFl[i] LIKE "*" & ModuliVari.$_FlgNmTab & "*"   'Cerca dentro la stringa $_RgFl(i) la sosttostringa ModuliVari.$_FlgNmTab
    IF b_Esito = TRUE THEN
        i_PoStri = InStr($_RgFl[i], "VALUES(")
        IF i_PoStri <> 0 THEN
            i_Lun = Len($_RgFl[i])
            $_RgRecDB = Split(Right($_RgFl[i], i_Lun - (i_PoStri + 5)), ",")
            i_TotElRg = $_RgRecDB.Count - 1
            FOR i_Ind = 0 TO i_TotElRg
              $_RgRecDB[i_Ind] = Replace($_RgRecDB[i_Ind], "(", "")         'Elimina dalla stringa tutti i crt "("
              $_RgRecDB[i_Ind] = Replace($_RgRecDB[i_Ind], "'", "")         'Elimina dalla stringa tutti i crt "'"
              $_RgRecDB[i_Ind] = Replace($_RgRecDB[i_Ind], ")", "")         'Elimina dalla stringa tutti i crt ")"
            NEXT
            SELECT CASE ModuliVari.$_FlgNmTab
                      CASE "piancont", "PianCont"
                          RecTab_cp = DB_Connection.Create("piancont_cp")
                          ME.Popolapiancont_cp
            END SELECT
        ENDIF
    ENDIF
  NEXT
END
PUBLIC SUB Popolapiancont_cp()

  IF $_RgRecDB[0] <> NULL THEN
    IF $_RgRecDB[0] <> "NULL" THEN      'abbandonono di eventuali record con chiave primaria = "NULL" 
        SELECT CASE $_RgRecDB[3]
                CASE NULL, "NULL"
                    $_RgRecDB[3] = "0"
        END SELECT
        TRY DB_Connection.EXEC("INSERT INTO piancont_cp VALUES(" & Int(Val($_RgRecDB[0])) & ", '" & $_RgRecDB[1] & "', '" & $_RgRecDB[2] & "', '" & Int(Val($_RgRecDB[3])) & "')")
        IF ERROR THEN
            Message.ERROR("Attenzione! ->  ERRORE n°" & ERROR.Text & Chr(10) & Chr(10) & "durante la registrazione della ContabFam.db!piancont_cp'" & Chr(10) & Chr(10) & " il programma verrà chiuso")       
            FMain.Close
        ENDIF
    ENDIF
  ENDIF
END

Per completezza riporto qui alcuni record del file .txt di partenza.
Citazione
PRAGMA foreign_keys=OFF;
BEGIN TRANSACTION;
CREATE TABLE 'ComponFam'  ( 'NuProCompFam' INTEGER, 'NomeCompFam' VARCHAR(20) DEFAULT NULL,  PRIMARY KEY ( 'NuProCompFam') );
INSERT INTO "ComponFam" VALUES(1,'Famiglia');
CREATE TABLE 'CausaliFreq'  ( 'DescrCausFreq' VARCHAR(100), 'DtUltCausFreq' INTEGER );
INSERT INTO "CausaliFreq" VALUES('Vitto',20090601);
INSERT INTO "CausaliFreq" VALUES('bar',20090525);
CREATE TABLE 'PianCont'  ( 'NumVoce'  PRIMARY KEY, 'NomeVoce' VARCHAR(50) DEFAULT NULL, 'ContrPartSiNo' CHAR(1) DEFAULT NULL, 'DtPrimoUso' INTEGER DEFAULT NULL );
INSERT INTO "PianCont" VALUES(10000000,'ATTIVO','N',NULL);
INSERT INTO "PianCont" VALUES(10100000,'CASSA','N',NULL);
INSERT INTO "PianCont" VALUES('00000000','Record Flag nuovi inserimenti','S','NULL');
INSERT INTO "PianCont" VALUES(NULL,'NULL','NULL','NULL');                   in questo record la primary key ha volre NULL
COMMIT;

A questo punto, in mancanza di osservazioni, andrò a porre [risolto] nel 1° post.
 :D ;D
Ciao.
:ciao:

Offline Ceskho

  • Amministratore
  • Senatore Gambero
  • *****
  • Post: 3.778
  • Vi Veri Veniversum Vivus Vici
    • Mostra profilo
    • Pagina Personale
Re: Trattamento file .txt con record a lunghezza variabile
« Risposta #11 il: 02 Febbraio 2010, 00:14:25 »
[RISOLTO] lo può aggiungere chi ha aperto il topic quando è soddisfatto delle risposte....se sei soddisfatto ed hai ottenuto quello che cercavi puoi benissimo inserirlo nel titolo...:-)