Newsgroup: it.comp.lang.c++
Titolo: lettura file misto

Ho a che fare con un file composto per metà da testo (xml) e per metà da dati 
binari. Le due parti sono separate dalla riga: <!-- END XML -->
Per poter parsificare e validare con libxml2 devo estrarre la parte testuale da 
quella binaria. Al momento ho trovato questa soluzione:
	ifstream iFile(pFileName, ios::in);
	string line;
         string::size_type pos = string::npos;
         char * buffer;
         int length;
         while (getline(iFile, line)) {
             // Ignore empty lines
             if(! line.empty() )  {
                 pos = line.find("<!-- END XML -->");
                 if (pos != string::npos) {
                     length = iFile.tellg();
                     buffer = new char [length - 17];
                     iFile.seekg(0, ios::beg);
                     iFile.read(buffer, (length - 17));
                     iFile.close();
                     cout.write(buffer, (length - 17));
                     xmlDocPtr doc;
                     doc = xmlReadMemory(buffer, (length - 17), "buffer.xml", 
NULL, 0);
                     if (doc == NULL) {
                         fprintf(stderr, "failed to parse the including file\n");
                         exit(1);
                     }
                 }
             }
         }
Voi che ne pensate ? A me non piace tanto dover leggere il file riga per riga, 
fino a quando non trovato la fine.
Consigli, opinioni e quant'altro sono ben accette.
Grazie,
Obelix.

 
sei stato molto preciso postando l'intero codice, eppure io ho 
lo stesso un dubbio : è conoscibile a priori l'ordine di 
grandezza dei files che dovrai "parserizzare" (eh he he, io 
quella parola amo storpiarla così !) ?
Voglio dire, se puoi sapere in anticipo che i files saranno a 
priori, che so, inferiori a pochi MB (sui computer attuali), 
potresti molto efficientemente (velocità) e facilmente (poco 
codice da scrivere), caricare l'intero file in ram (array di 
unsigned char, ad esempio) con una sola lettura (binaria). A 
quel punto una funzione di ricerca a stringa (intesa all'antica, 
non come tipo std::string) è triviale da scrivere, o ce ne sono 
di standard, ma ovviamente guadagni vari aspetti (che poi i 
guadagni siano o meno significativi dipende dal contesto 
ovviamente, claro) :
1) usi un solo livello (implicito) di bufferizzazione nell'I/O, 
quello di sistema operativo, che ha la massima efficienza
2) eviti ogni forma di gestione dinamica (riallocazioni, 
deallocazioni, o almeno codici di controllo overflow tipici 
delle stringhe dinamiche "elastiche")
ovviamente il difetto principale è il consumo assoluto DI PICCO 
di memoria. Solo tu puoi sapere se è possibile stimarlo a 
priori. Se i files sono medio-piccoli, è adeguato, se sono dei 
giganti, potrebbe non esserlo più.
Per la lettura non so bene come consigliarti .... io ho il 
difetto di usare sempre routine che non sono più standard (stile 
C) o peggio ancora chiamate alle API di sistema (tipo ReadFile 
di windows), e quindi lascio agli esperti, eventualmente, di 
consigliarti funzioni efficienti di lettura binaria da 
file-handle che fungano su grossi array.
ciao
Soviet


 Per la lettura non so bene come consigliarti
Il metodo piu' efficiente per implementare questa tecnica e' usare i 
memory-mapped files, ma non fanno parte della libreria standard, quindi 
o use le API del sistema operativo o usi una libreria non standard.
Un metodo piu' succinto e standard, e' invece il seguente.
Dopo queste direttive:
   #include <iostream>
   #include <fstream>
   #include <sstream>
Si puo' leggere il file il cui nome e' contenuto nella variabile 
"filename" usando il seguente codice:
   std::ostringstream oss;
   oss << std::ifstream(filename).rdbuf();
il contenuto del file e' una std::string accessibile tramite l'espressione:
   oss.str()
-- 
     Carlo Milanesi
 
http://digilander.libero.it/carlmila