Newsgroup: it.comp.lang.c++
Titolo: caricare in memoria un file intero

fino ad adesso quando avevo voglia di inserire l'intero contenuto di un 
file in memoria ho sempre utilizzato un sistema brutto e poco efficiente...
per esempio qualcosa del genere
ifstream input;
input.open("file.inp");
char a;
vector<char> buffer;
while (input.getc(a)) buffer.push_back(a);
al di là dell'utilizzo del vector al posto di una stringa da connettere 
magari tramite strstream quello che mi piacerebbe ottimizzare è il 
contenitore prima del caricamento del file.
In particolar modo mi piacerebbe conoscere la dimensione del file prima 
di scorrerlo tutto.
In secundis... leggere un file char dopo char è un sistema lento ?
-- 
Hai recensioni nel cassetto di musica, cinema, letteratura,fumetti??
Ascolta e pentiti e se hai tempo vergognati
http://tonysuper.altervista.org

 di scorrerlo tutto.
usa seekg e tellg dell'ifstream:
std::ifstream ifile("ciao.txt");
ifile.seekg(0, std::ios::end);
std::streampos len = ifile.tellg();
ifile.seekg(0, std::ios::beg);
char *filebuff = new char[len];
ifile.read(filebuff, len);
// ...
delete [] filebuff;
ciao
twism

 usa seekg e tellg dell'ifstream:
bene! riguardo l'efficienza... queste funzioni non otterranno mica la 
dimensione scorrendo (a mia insaputa) l'intero file?


 dimensione scorrendo (a mia insaputa) l'intero file?
seekg lo fa:
ifile.seekg(0, std::ios::end); 	/* posiziona il get-pointer all'offset 0
				   partendo da std::ios::end
				*/
 
ifile.seekg(0, std::ios::beg);	/* posiziona il get-pointer all'offset 0
				   partendo da std::ios::beg
				*/
ciao
twism

 In secundis... leggere un file char dopo char è un sistema lento ?
*Spaventosamente* lento; in genere si usa un buffer
pari alla dimensione della pagina del sysop, 4096 bytes;
dimensioni superiori non offrono miglioramenti in termini
di prestazioni.
Tieni presente che le letture da disco non portano i dati
direttamente in memoria utente: il kernel legge le pagine
in un buffer in kernel space e *poi* le ricopia in user 
space (a memo di rimappare i processi nello spazio di 
indirizzamento del kernel, ma non so se Linux lo fa);
questo può portare ad un overhead non ignorabile per grosse
quantità di dati: se la velocità è un requisito essenziale
e devi leggere file molto grossi valuta l'uso della mmap().
SiMoStro

 
con il sistema suggerito (poco standard :-) ... ci sono degli errori*)
ho letto files di 500 mega in una frazione di secondo
*meglio fare cosi'che compila dappertutto .. non sempre streampos sono 
degli interi ... spesso sono dei puntatori
std::ifstream ifile("ciao.txt");
ifile.seekg(0, std::ios::end);
std::streampos fine = ifile.tellg();
ifile.seekg(0, std::ios::beg);
std::streampos inizio = ifile.tellg();
int len=fine-inizio;
char *filebuff = new char[len];
ifile.read(filebuff, len);
// ...
delete [] filebuff;
quello che mi piacerebbe pero' č usare una string al posto della char* 
senza usare istringstream e senza creare una char* temporanea...
qualcosa tipo
string buffer;
buffer.reserve(len);
????????????? // istruzione che manda tutto nella string... pero' se 
faccio ifile >> buffer; si prende solo la prima parola


 seekg lo fa:
Mica detto. Se il filesystem sottostante supporta l'indirizzamento
diretto (come nel 99,99% dei casi) molto probabilmente lo spostamento
risulta in una semplice addizione.
Ciao,
Nicola

 faccio ifile >> buffer; si prende solo la prima parola
si operator>> legge fino a un whitespace o \0. Magari c'e' qualche
manipolatore per cambiare questo comportamento ma non me ne viene in
mente nessuno.
ciao
twism

 degli interi ... spesso sono dei puntatori
Scusa ma questa frase non l'ho capita.
Che tu riesca a leggere 500MB in una frazione di secondo
un byte alla volta non ci credo neanche se lo vedo :-)
Che tu possa "effettivamente" leggere 500MB in qualsiasi
modo in "frazioni" di secondo va al di la delle più rosee
aspettative di throughput di qualsiasi disco fisso "commerciale"
(hai mica roba militare?) :-)
Che una syscall non compili dappertutto è poco ma sicuro,
che una syscall POSIX, X/OPEN e 4.3BSD compliant tu la possa
(debba) trovare su qualsiasi sistema operativo UNIX e Linux
è altrettanto sicuro.
Il resto è ovviamente opinione.
Così come la mia convinzione che a volte si debba sacrificare
lo "standard del linguaggio" per uno "standard di syscall" è
a sua volta un'opinione.
Rimane il fatto che qui siamo su i.c.l.c++, quindi la strada da
te imboccata è senz'altro quella (qui) più consona.
SiMoStro

 te imboccata è senz'altro quella (qui) più consona.
ottime prestazioni comunque anche con visual studio toolkit 2003, male 
intel...


 intel...
Il compilatore C++ di Intel? Strano, dovrebbe essere il migliore
a disposizione... purtroppo non ho mai avuto il piacere di provarlo,
per BSD non credo che esista...
SiMoStro