C nyelv: alábbi fájlmásoló programba hogy lehet időmérést, százalék-kijelzést tenni? (bővebben lent)
Az alábbi kis programot hogyan, miképpen lehetne úgy átírni, hogy a bemeneti fájl tartalmát kimeneti fájlba másolja, mindig annyit olvasson be, amennyi a memóriába éppen befér? A másolás előrehaladásáról tájékoztasson százalékos formában, de csak akkor ha az adott százalékos érték osztható 10 számmal?
Azt miképpen lehet megoldani, hogy az időt is mérje, másolás elejétől és a végén írja ki mennyi ideig tartott a teljes másolás?
Ezek nagy részét másik programozási nyelvben meg tudom valósítani (kivéve a "memóriába annyit olvasni mint amennyi belefér problémát"), de C nyelven sajnos nem.
Milyen függvények kellenek? A fseek-ről azt olvastam például, hogy csak 2 GB méretű fájlokig jó.
Malloc függvény kell talán a memóriába történő olvasásra.
Ha ekkor nincs puffer, mert a memóriába annyi van olvasva mint amennyi belefér, akkor ha meg szeretnék változtatni egy-két bájtot például a fájlon, hogy kimenetbe már a változtatás kerüljön, azt hogy kell csinálni?
Sajnos, hibás a program:
fajlos.c: In function ‘main’:
fajlos.c:15:1: error: expected declaration or statement at end of input
}
#include <stdio.h>
int main(int argc, char *argv[]){
FILE *be, *ki;
int ertek;
be=fopen(argv[1],"rb");
ki=fopen(argv[2],"wb");
while((ertek=fgetc(be))!=EOF){
ertek=fputc(ertek,ki);
fclose(ki);
fclose(be);
return 0;
}
Ezt nem így szokás.
Mit jelent nálad az, hogy a memóriába belefér?
Csak mert létezik swap file és az oprendszer annyi memóriát foglal le, amennyit csak kérsz tőle.
Kell egy puffer méret. Ez lehet bármennyi, de lehet a file tényleges méretével arányos is. Ezt kell lefoglalni, ebbe beolvasni egy file szakaszt, azt kiírni a kimeneti file-ba egészen addig, amíg el nem fogy a beolvasnivaló (EOF).
Az idő mérése meg úgy van, hogy a másolási folyamat kezdete előtt mérsz időt (T0), majd utána is (T1) és a T1-T0-t kiiratod.
Arra gondolok "amennyi belefér memóriába" fájlbeolvasás alatt, mint amit a másolóprogramok szoktak, feltételezem, hogy azok nem fix méretű puffert (pl. 64 MB) használnak, hanem oprendszertől lekérik, hogy "mennyit tud egyszerre beolvasni", aztán kiírják.
Időmérést tudom elméletben (más programozási nyelven gyakorlatban is), csak bonyolult számomra C nyelven megvalósítani.
Százalékszámítás pedig: aktuális fájlpozíció * 100 / fájlméret
Jelenleg miért nem működik a program, tudsz benne segíteni, hogy működjön?
Rájöttem a hibára, hogy miért nem működött, működik most, de működésével nem örvendeztet meg túlzottan, mert egy bájtot másol át...
Elnézést, hogy nem tettem fájlmegosztó oldalra a forráskódot, gondoltam: "ilyen rövid kód esetén ez lehet praktikusabb ha ide másolom):
#include <stdio.h>
int main(int argc, char *argv[]){
FILE *be, *ki;
int ertek;
be=fopen(argv[1],"rb");
ki=fopen(argv[2],"wb");
while((ertek=fgetc(be))!=EOF){
ertek=fputc(ertek,ki);
fclose(ki);
fclose(be);
}
return 0;
}
Írtam, hogy két megoldás lehetséges. Az egyik, hogy fileméret specifikusan határozod meg a puffer nagyságát, vagy fix méretet veszel és azt foglalod le.
A file-ok másolásához 64 MB-os puffer baromi sok. Ennek töredéke, 64 kB is elég a gyakorlatban, vagy még ennél is jóval kevesebb.
Ha alterálni szeretnéd a file tartalmát bizonyos helyeken, akkor csak átírod a puffer adott pozícióján (offset) lévő byteokat és ezt a tartalmat írod a kimenetre.
A százaléknál egy while-ba foglalod a pufferbe olvasást, a százalék-érték megjelenítését és a file-ba írást is.
Itt már talán számodra is látszik, hogy 64 MB mennyire nem lesz jó puffernek, hiszen a file-ok nagyobb része ennél sokkal kisebb.
A másolás előtt lekéred a file méretét, ez lesz a 100 %, a beolvasott pufferek száma meg adja az aktuális, megjelenítendő százalékértéket. Persze a pufferméret függvényében.
Köszönöm a választ.
Több GB méretű fájlok másolására gondoltam. Ekkor a 64 KB puffer elég lassú lehet, legalábbis én ezt tapasztaltam más programozási nyelveken.
Ha történetesen a puffer a lekért fájl mérete, ami mondjuk több mint 10 GB akkor is lekezeli, megoldja a C nyelvű program?
Én csak a "bájt méretű tömb pufferként történő használatát" ismerem, a másik módszert nem igazán, amikor a puffer a fájl mérete, vagy "lekéri oprendszertől hogy mennyit olvashat be".
Nem lassú az.
Ezeket a programokat úgy kalibrálják, hogy az átlagot veszik alapul. Tehát megnézik mondjuk egymillió file méretét, abból átlagot vonnak és annak megfelelően alakítják ki a puffert. Legalábbis régen így történt. Ma már rugalmasabbak (vélhetően) és a másolandó file mérete lehet a kindulópont.
A sebesség nem csökken számottevően kisebb pufferméret esetén sem, ezt akár le is tesztelheted.
Arra is tekintettel kell lenni, hogy multitaszk környezetben más programok is futnak, nem célszerű őket, vagy magunkat a swap-re kiszorítani néhány sec remélt előnyért.
A sok GB-os fileok mindenhogy lassúak lesznek, de nem ezek másolása a gyakori.
"Ha történetesen a puffer a lekért fájl mérete, ami mondjuk több mint 10 GB akkor is lekezeli, megoldja a C nyelvű program?"
Persze. Egy terabyte-ot is képes másolni, a korlát itt max. az oprendszer képessége lehet.
Mert utóbbi mondjuk egy régebbi DOS, Windows vagy Linux esetében még partíciót sem képes lekezelni ami 1 TB-os, nem, hogy ekkora file-okat.
A másoló rutinnak meg olyan mindegy, hogy négyszer, netán négyezerszer fordul vagy esetleg negyvenezerszer.
Én sok helyen olvastam, hogy nagy fájlok esetén jelentősen lassabb mintha egy sok MB-s puffert deklarálnánk, mert minél több "lemezhez fordulással" jár a másolás, annál lassabb lehet jelentősen. Mondjuk az igaz, hogy nem feltétlenül nagy fájlok másolása fordul elő mindig.
Tömb deklarálása pufferként ez a járható út?
például:
int puffer[65535];
Kapcsolódó kérdések:
Minden jog fenntartva © 2025, www.gyakorikerdesek.hu
GYIK | Szabályzat | Jogi nyilatkozat | Adatvédelem | Cookie beállítások | WebMinute Kft. | Facebook | Kapcsolat: info(kukac)gyakorikerdesek.hu
Ha kifogással szeretne élni valamely tartalommal kapcsolatban, kérjük jelezze e-mailes elérhetőségünkön!