[ Iznogud @ 12.08.2004. 21:26 ] @
Pisem jedan program u C++ koji omogucava korisniku da izabere jedan ili vise fajlova, zatim kodira te fajlove po odredjenom algoritmu i salje ih netom.
Problem, dilema, je u tome sto ne znam kako da smesti kodirane fajlove u mermoriju. Zamislio sam da definisem varijablu tipa "char* var[]" gde bi u var[0] kodirao jedan fajl, zatim u var[1] drugi, itd. koliko korisnik vec izabere.
Koliko je ovo dobra ideja?
Znam, ako je fajl nekoliko desetina MB (ne daj boze stotina) javlja se problem sa memorijom.
Mozda neki savet....
[ filmil @ 12.08.2004. 21:44 ] @
Citat:
Koliko je ovo dobra ideja?
Bojim se da ideja nije sjajna, ali za neke algoritme je prosto neizbežna. Recimo za turbo-kodiranje, od velike važnosti je brz pristup bajtovima koji su na slučajnim mestima u datoteci.

S druge strane, ako postoji mogućnost da fajlove učitavaš u malim porcijama, te porcije obrađuješ i odmah ih upisuješ na disk, onda je to verovatno najbolje moguće protočno rešenje. Primer bi bio ako želiš da svaki bajt u fajlu uvećaš za 1 po modulu 256. Za to ti je potrebno da u jednom trenutku imaš samo jedan bajt datoteke u memoriji, makar originalna datoteka bila velika 10MB ili 10GB.

Sa treće strane, možeš da razmotriš mogućnost da napraviš kopiju fajla na disku, zatim ga otvoriš sa slučajnim pristupom (random)

Četvrta mogućnost je da koristiš mogućnosti operativnog sistema i da mapiraš deo datoteke u memoriju. Šetanje po datoteci se onda svodi na šetanje po memoriji, a operativni sistem vodi računa da je ispravan deo datoteke u memoriji.

f
[ zvrba @ 13.08.2004. 08:09 ] @
Citat:
filmil:
Četvrta mogućnost je da koristiš mogućnosti operativnog sistema i da mapiraš deo datoteke u memoriju. Šetanje po datoteci se onda svodi na šetanje po memoriji, a operativni sistem vodi računa da je ispravan deo datoteke u memoriji.

Tu opet postoji problem sa memorijom: adresni prostor procesa je ogranicen i na 32-bitnoj arhitekturi i modernim kernelima redovito iznosi 3GB. Dio toga je rezervirano za NULL pointer checking, dio potrose DLL-ovi, dio potrosi program i tako..

Za mapiranje cijelog fajla u memoriju mora biti slobodno onolika kolicina UZASTOPNE (ne fragmentirane) virturalne memorije koliko je velicina fajla. Ako nemas dovoljno, opet ti ne pomaze.

Problem se moze rijesiti mapiranjem malih chunkova fajla pocevsi od nekog offseta, ali to opet komplicira stvar.

Uostalom, rijetko koji algoritam zahtijeva slucajan pristup bilo kojem bajtu datoteke. Ako ti nije bitna brzina napravi wrapper klasu za fajlove, npr:

Code:

class Indexedfile {
  FILE *fp;
public:
  IndexedFile(const char *fname);
  unsigned char operator[](unsigned int off) const;
};

unsigned char IndexedFile::operator[](unsigned int off) const
{
  if(fseek(fp, off, SEEK_SET) != EOF) {
    int ch = fgetc(fp);
    if(ch != EOF) return ch;
  }
  /* greska - izvan granica fajla ili pri citanju znaka */
}


Mozes dodati dodatni kod unutar klase koji cache-ira lookupove.. npr. std::map sa offseta na vrijednost, a mapa nikad nema vise od npr. 128 tisuca elemenata..

Ako ti treba i pisanje po fajlu, mozes napraviti operator[] koji vraca neku Proxy klasu.. Proxy klasa ima operator konverzije na unsigned char i overloada operator= koji onda zapisuje promijenjeni bajt u datoteku..

Uglavnom, sa ovakvim pristupom mozes napraviti trade-off brzina/potrosnja memorije kakav ti vec treba...