Pascal: fájlokból rekordokba történő beolvasási probléma? (bővebben lent)
Van egy adatbázis, amelyben az adatok egyszerűen, "," karakterrel elválasztva szerepelnek. Ezeket szeretném beolvasni rekordokba.
A program bizonyos fájlnál kiakad, tapasztalataim szerint az 5. fájlnál. Nem tudom, ez memória hiba -e, vagy másnak köszönhető.
Ez az adatbázis konkrétan a GTFS adatbázis, amely a BKK menetrendet tartalmazza.
Mondjuk nem csodálom, ha kiakad, mert az összes fájl mérete 322 MB körül van, igaz gépben 3 GB van, de nem tudom miként kezeli a memóriát a program.
Mit lehetne tenni, hogy a memóriában elférjen, "packed record"-ot használni vagy egyebet?
Aki tud más programozási nyelven megírt kódot, ami jól lekezeli, az érdekelne.
Python-t találtam, de az egyenlőre számomra még túl bonyolult, szerteágazónak tűnik mert nem értek hozzá. :-(
Egyenlőre Pascal-ban szeretném megoldani, ha ez lehetséges.
Az általam írt program hivatkozása:
pastebin(pont)com/bgtsp98N
A GTFS adatbázis:
A program relatív útvonalon keresi a fájlokat, tehát zip fájl kicsomagolása után a fájlok mellé másolva aktuális könyvtárban nyitja meg őket.
A fájl első sorát azért nem teszem be sehova, mert a fájlok első sora mindig a fejléc, arra pedig nincs szükségem, mert azért hoztam létre a rekordokat.
Olvas függvényben a "pos" eljárással elegánsabb lett volna léptetni és abban sem vagyok biztos, ha üres egy mező (",,") azt jól kezeli -e, bár ekkor elvileg a hossza 1 és nem tartalmaz karaktert...
Mit csináltam rosszul?
Szia.
Biztosan nem a memória a gond.
A hiba a következő: az olvas függvényedben nem jól kezeled le az üres adatot.
Ha átszerkeszted a kódot, úgy hogy az első fájl a "routes.txt" legyen és a feldolgozás során is ez legyen az első (tehát a Case-t is átirod) akkor rögtön megáll hibával.
Ha debugolod a kódot, és nézed a változókat, akkor azt látod, hogy az első 3 adatot beolvassa, és utána áll meg hibával.
Ha belenézel a fájlba, akkor ez az első rekord (második sor) :
BKK,0050,5,,3,"Pasaréti tér / Rákospalota, Kossuth utca",009FE3,FFFFFF,
Látszik, hogy az "5" után nincs adat, valószinű ez a gond (pl. nem tud 0 karaktert törölni a stringből - de ez csak tipp)
Sok sikert. Üdv.
Igen, az üresen hagyott mezőt, amit ",," jellel jelölnek, ez nincs lekezelve...
Egyébként tényleg soronként kell beolvasni és "vesszők mentén szétbontani" az adatokat.
Illetve persze lehet beolvasni egyben is az egész fájlt és úgy dolgozni rajta, vagy karakterenként.
"Érdekelne az is, miként lehet Pascal-ból az egész adatbázist SQL-be exportálni, majd szintén Pascal-ból lekérdezéseket hajtani végre rajta."
Adjunk árajánlatot? :))
Elég rég óta foglalkoztam pascallal. Sok éven át pascaloztam. Most csak ezért felraktam (ezen a gépen nem is volt fent még), de le is törlöm. Ahogy néztem továbbra is fennáll, hogy a magas szintű prog. paradigmák nyelvi szintű támogatása mint pl generikus típusok, fizetős delphi változat támogatja. Őrült módon korlátozottnak érzem magam, gondoltam többet írok, de kösz bőven elég volt a pascalból, amúgy is egy csalódás volt régen a normális támogatottság miatt főként. Inkább a c még ha még fapadosabb akkor is, legalább kiemelkedő szintű a támogatottsága. Na de ha c akkor inkább már c++, az mégiscsak emberközelibb mint a c és úgymond "testvére". Na de ha választanom kéne akkor python. Ha a teljesítménykirtikus a dolog akkor meg vagyok olyan rafinált hogy a teljesítménykiritkus részt kioptimalizálom c/c++ -ba a többi marad pyton-ba.
Free pascalos változat : pastebin pont com/kBqqNTRQ
Azért az több mint felháborító, hogy nincs egy split se, csak ilyen saját magad összerakott kínlódásokat találtam, ezt én kínlódtam össze saját kútfőből. Ha van és én voltam béna esetleg mert nem találtam, akkor is jól el van dugva.
Na de ugye pascal-ba unitok adják a keretrendszert, készítsünk hozzá, és építkezzünk így elkülönített saját és standard stb unitikból : pastebin pont com/ste0v4gC
Ugyanez a demo pythonba: pastebin pont com/9xJi7H0x
Egyébként meg teljesen felesleges az egészet berántani a memóriába. A memória használattal kapocsolatba számolj úgy hogy pascalba alsó hangon ha nincs még plusz overhead akkor egy sima mezei string 256 bájtot foglal. A 0.-ik indexen 1 bájtos hosszúságot jelző érték van, utána a string karaktererei max 255 darab, ha nincs annyi akkor a fennmaradó rész kihasználatlan. A delphi-s féle dinamikus string máshogy fest (nálam nem ez lépett életbe a ObjFPC diretktíva ellenére se). Az úgy fest, hogy van hossz értéket jelölő szám 4 bájt, de lehet hogy 8 bájt 64 bites rendszerbe, utána egy pointer ami ugye 32 bites rendszerbe 4 bájtos 64 bitesen 8 bájtos ez a pointer a string karaktereinek dinamikusan lefoglalt memóriaterület kezdőcímére mutat és akkora méretű ahány karakteres, de pluszba hozzátesz hogy vannak karakterek melyek több bájtosok és a valódi memória foglalás pedig gyakorlatilag valamely kettő hatvány egész számú többszöröse. Az array of string diamikus memóriafogalása meg úgy történik mint a delphis stringeké elvben csak ott nem karakterek kezdőcímére mutat hanem pointerek kezdőcímére amelyek tovább mutatnak a stringekre, szóval (ugye gondolom 64 biten vagy ezért) 8 bájtot hozzátesz minden egyes stringhez pluszba még azon felül amiről szó volt. A setLength-el így meg lehetőleg ne növelj dinamikus tömböt egyesével. Így jól szétfragmentálod a heap-et. Ugyanis az azt csinálja hogy lefoglal adott számú elemet vagyis alloc memory-t csinál majd folyamatosan realloc-olsz. Ami mit jelent gyakorlatban? Azt hogy először lefoglalod majd amikor növeled akkor keres egy arra alkalmas egybefüggő memóraterületet és oda lemásolja a régit majd a régit felszabadítja. Ha a tényleges lefoglat terület több mint a logiailag lefoglat akkor ha minden igaz nem foglal újra, na de lég sok felesleges újrafoglalást csinál akkor is. Ha csökkented a tömb méretét akkor is ezt csinálja csak fordítva és akkor ugye lecsonkítja a tömböt. Éppen ezért ideális az lenne ha tudnánk hány elem kell és akkora tömböt foglalunk, de sokszor nem ideális a helyzet, ekkor meg az az optimális stratégia (ami egy bevett szokás megírt függénykövtárakba implementálva pl) hogy valamennyit előre lefoglal ha kevés akkor duplázza a tömb méretét.
Kapcsolódó kérdések:
Minden jog fenntartva © 2024, 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!