JavaScript: fájkezelés

3. Fájlok kezelése

Az erőgyűjtés utolsó részében a fájlok kezeléséről lesz szó pár ismertető példával együtt.

1

Hogyan tudunk az oldalra egy fájlt feltölteni?

Holnapok esetén számtalanszor van példa arra, hogy egy fájlt kell tallózni, ami aztán feltöltésre kerül, és az oldal valamit kezd vele. Ezt a folyamatot több módon is végre lehet hajtani, de az alapja mindegyiknek hasonlóan működik. Mivel a Javascript kliens oldalon fut, ezért minden esetben azzal kell kezdeni, hogy a felhasználó kiválasztja a feltölteni kívánt fájlt. Ehhez a HTML biztosít egy beviteli mezőt, így nem kell vele különösebben foglalkozni.

Amint kiválasztásra került a fájl, egy Javascript függvény veszi át a folyamatot. A függvény közvetlenül le tudja kérdezni a fájl nevét és típusát, viszont a tartalom beolvasása már más kérdés. Nagy fájlok esetében ez komoly művelet lehet, ezért ezt mindig egy aszinkron függvény végzi el. A beolvasást egy FileReader objektum végzi. Az onload függvénynek meg kell adni hogy mit csináljon ha végzett. Itt lehet feldolgozni a tényleges tartalmat. A lentebb látható példa a fájl tartalmát egyszerűen beleírja az oldalon lévő szövegmezőbe, de a tartalom akár karakterenként is feldolgozható. Egy split("\n") függvényhívással fel lehet bontani a tartalmat sorokra, amennyiben a feldolgozáshoz ez szükséges.

« Előző | Lap eleje

2

Hogyan tudunk letöltendő fájlt generálni?

Előfordul az is, hogy a honlapon látott információkat a felhasználó szeretné fájl formájában letölteni. Sok esetben nem áll rendelkezésre a fájl valamilyen távoli szerveren, főleg hogy a változó tartalmat helyben kell generálni. Erre a HTML-ben alapból nincsen lehetőség, hanem valami egyéb módot kell találni a probléma megoldására. Több lehetséges megoldás is található egy rövidke keresgélés után, az alábbi kód egy lehetőséget mutat be.

A megoldás lényege, hogy a letöltés gombra kattintva az oldal egy linket generál a szövegmező tartalmából. A link egy újonnan létrehozott eleme az oldalnak. A hivatkozás céljának létrehozását egy Blob objektum segíti. A script ezután úgy tesz, mintha a felhasználó a hivatkozásra kattintott volna, ezáltal a letöltés maga elkezdődik. A végén kitörli a hivatkozást az oldaról, hiszen csak átmenetileg volt rá szükség, amíg a letöltés elindul.

« Előző | Lap eleje

3

Reguláris kifejezések

Egy fájl tartalmának értelmezésekor nem mindegy hogy milyen a fájl szerkezete. Léteznek kötött szerkezetű formátumot (pl. csv, xml), de sok esetben a fájl tartalma kevésbé kötött. A log fájl esetében például tudjuk hogy minden sor egy eseményt ír le, viszont eseményekből sok féle van, és mindegyik másképp néz ki. Ahhoz hogy egy ilyen eseményt elemezni tudjunk, először meg kell állapítani a típusát. Tudjuk hogy milyen típusú események vannak, és az azokhoz tartozó sorok hogyan néznek ki.

A reguláris kifejezések lehetővé teszik, hogy egy szabályt alkossunk, ami leírja egy esemény megjelenési módját. A reguláris kifejezéseket kezelő motorok ezután képesek a kifejezést egy szövegre illeszteni, és megállapítani hogy a szöveg megfelel-e a szabálynak. Ez ad lehetőséget egy log üzenet típusának eldöntésére. Ezen felül a reguláris kifejezések segítségével a szöveg érdekes elemeit el is lehet menteni az illesztés közben, nem szükséges utólagos elemzés.

Javascript-ben reguláris kifejezéseket egy RegExp objektum segítségével lehet kezelni, de sima szövegként is megadható. Online leírás: Javascript reguláris kifejezések.

A legegyszerűbb módja egy reguláris kifejezés megadásának, ha a /kifejezés/ szintaxist használjuk, ahol a kifejezés helyére kell a szabályokat írni. Például, ha egy olyan szabályt szeretnénk, ami azt keresi meg, hogy a szövegben megtalálható-e az "alma" szórészlet, akkor ezt /alma/ módon tesszük meg. Ezután tetszőleges szövegre ellenőrizhető hogy igaz-e rá a szabály. Amennyiben igen, még azt is megkérdezhetjük, hogy melyik pozíción.

Ennél bonyolultabb kifejezéseket is meg lehet adni természetesen. Ha egy karakter ismétlődését szeretnénk elvárni, arra több lehetőség is van. Egy *-ot utánna írva akárhányszor ismétlődhet, míg +-t írva utánna legalább egyszer meg kell jelennie. Ha ?-et teszünk, akkor vagy nullaszor vagy egyszer fogadjuk csak el, többször nem.

Példának nézzünk meg egy olyan kifejezést, ami akkor illeszkedik egy szövegre, ha abban van legalább egy darab o karakter. Ez egyszerűen /o/ lenne. Viszont ha az a cél, hogy egy egész sorozatot találjunk meg, akkor /o+/-t írhatunk. Ilyenkor azt is meg lehet jeleníteni, hogy mi az az illeszkedő része a szövgnek, amit megtalált a program. Figyeljünk arra, hogy az /o*/ nem jó, mert az a nulla darab o betűt is elfogadná, ami minden szövegre igaz.

Természetesen a korábban említetteket lehet kombinálni, hogy osszerakjunk egy hosszabb kifejezést, de még sok dologról nem is volt szó. Speciális módon meg lehet adni, hogy a szöveg egy helyén ne csak egy karakter legyen jó, hanem egy teljes karakterhalmaz. Ha [] zárójelek között megadunk pár karaktert, akkor azok közül bármit választhat. A /[abc]/ regulárs kifejezés minden szövegre illeszkedik, amiben van legalább egy a, b, vagy c karakter. Az /alma[abc]/ kifejezés olyan szavakat keres, amiben az "alma" szó után jön egy a, b, vagy c karakter, pl. az "almafa" nem jó, de az "egyalmac" igen. Léteznek specális karakterek a gyakran használt halmazok jelölésére. A \w egy szöveg-be illő karaktert jelöl, vagyis bármit, ami kisbetű, nagybetű, vagy szám. Hasonlóan, a \d számjegyeket jelöl, a \s pedig whitespace karaktereket.

Ha már zárójelezést is használunk, akkor a módosítók nem csak egy karakterre, hanem egy komplett kifejezésre is vonatkozhatnak. A zárójelezés azonban nem csak erre jó. A zárójel egyben egy illesztendő rész-szöveget is jelöl, ahol is a zárójelen belüli részt az illesztés után külön is le lehet kérni. Az illesztés után, ahogy a fenti példa is mutatja, az eredmény 0-ás helyén található a teljes szöveg, amire a teljes kifejezést illesztette. Ha a kifejezés tartalmaz zárójeleket, akkor minden olya része a szövegnek, ami zárójelbe kerül, az eredmény későbbi helyein lesz.

Nezzünk egy példát egy kicsit kaotikusabb kifejezésre: /(\w+)(\s\d+\w+)?( [abc]+d*)/. Ez az elején egy akárhány karakterből álló szöveget keres: "(\w+)", ami zárójelben is van, tehát az illeszkedő részt külön el fogja menteni. Utánna egy opcionális rész következik: "(\s\d+\w+)?", ami egy whitespace karakterrel kezd, utánna valamennyi számjegy, majd valamennyi szöveges karakter. A kérdőjel azt jelenti utánna, hogy ez a rész vagy egyszer fordul elő, vagy egyszer sem. A zárójel kell azért, hogy a kérdőjel az egészre vonatkozzon, de emiatt az illeszkedő részt el is menti. A harmadik rész: "( [abc]+d*)", vagyi szóközzel kezdődik, majd tetszőleges mennyiségű de legalább egy karakter, melyek mindegyik a, b, vagy c. Ezután még jöhet akármennyi d betű, akár nulla darab is. És ez a rész is zárójelben van. Megjegyzés: ha egy zárójel csak azért van, hogy egy módosító működjön (mint a második résznél a ?), akkor megadhatjuk, hogy ne mentse el a rá illeszkedő részt. Ehhez a zárójel elejére a ?: két karaktert oda kell tenni, vagyis ha a második rész így nézne ki: "(?:\s\d+\w+)?", akkor nem mentené el a zárójelek közötti részt.

Nézzük meg a példát működés közben is! Figyeljük meg, hogy a kifejezés nem illeszkedik a teljes szövegre, csak egy részére, ezért azt is adja vissza a 0-ás pozíción. Az 1-es, 2-es, és 3-as pozícók az 1., 2., és 3. zárójeleken belüli részeket tárolják. Ha nem a text3, hanem a text4 szöveget ellnőriznénk, azt is elfogadná, hiszen a középső rész nem kötelező. Ez esetben a második zárójel helyét fent tartja, még akkor is a szövegre nem illeszkedik, és a 2-es pozíció értéke undefined lesz.

Egy összetettebb példa kedvéért vegyük a lentebb található kódot. Ez a szövegdobozba beírt szöveget sorokra bontja, és minden sort ellenőriz egy reguláris kifejezéssel. A használandó kifejezés kiválasztható a három beépített közül.

« Előző | Lap eleje

4

Oldd meg a feladatokat!

Kedves Bakonyi Bitfaragó Jelöltek!

Ebben a részben megismerkedhettetek a fájlok kezelésének módjaival, csakúgy mint a regulárs kifejezések alapjaival. Most következzen tehát a beadandó feladat, melynek lényege egy olyan oldal elkészítése, ahol egy tűzfal szabáyait lehet kezelni. Tűzfalként az iptables-t használjuk, melyről neten több leírás is található:
Link1
Link2
Link3
A honlapnak egy táblázatot kellene tartalmaznia, melynek minden sora egy-egy szabály adatait tartalmazza, pl:

Lánc Bejövő interfész Küldő címe Küldő portja Művelet
OUTPUT eth0 ACCEPT
INPUT 193.6.34.1/24 443 ACCEPT

Az üresen hagyott cellák nem jelentenek megkötést. Bizonyos opciókra vannak formai előírások, pl. a küldő illetve fogadó címe IP cím (193.6.34.1), ami esetleg az alhálózati maszkot is tartalmazhatja (a /24 a végén). Hasonlóan a port az csak egy szám lehet (bár elvileg megadható névvel is, mint "ssh", ezzel nem kell foglalkozni). A feladatban a táblázatot tudni kell módosítani, majd egy letöltés gombra kattintva szabályokat generálni belőlük. A Fenti táblázatbó generált szabályok:
-A OUTPUT -i eth0 -j ACCEPT
-A INPUT -s 193.6.34.1/24 --sport 443 -j ACCEPT
Az oldalnak csak a hozzáadó szabályokat kell kezelnie, tehát mindegyik -A-val fog kezdődni, ami után a lánc következik. Minden opciónak meg van a kötőjellel (1 vagy 2) kezdődő megnevezése, és utánna egy érték következik, valamilyen formátumban. Az iptables-nek sokkal több opciója van, mint amit a feladat kér, ezekkel nem kell foglalkozni. A feladat több opció kezelését is felsorolja majd, minél többet támogat a rendszer, annál több pontot ér.
A feladatnak van olyan része, ahol reguláris kifejezést kell írni, amit a szabályokra illesztünk. Itt feltételezhetjük hogy egy szabályban az opciók sorrendje nem változik, viszont semmi sem kötelező. Ehhez segítséget nyújthat a lentebbi kódrészlet. Figyeljétek meg hogy a reguláris kifejezésben melyik zárójelekben van ?:, jelezve hogy a zárójel tartalma nem érdekes. Szintén érdekes annak módja, hogy a -s opció esetén, ami a küldő címét adja meg, hogy néz ki a címre és az esetleges alhálózatra illeszkedő kifejezés.

Beküldhető feladatok:

  1. Az eddigiek alapján tehát készítsétek el a következő feladatokat:
    • Legyen egy táblázat, amiben a lehetséges opciók jelennek meg. A kezelendő opciók (minél több van, annál több pontot érnek a feladatok):1 0000|2 pont
      • Lánc (-A)
      • Bejövő interfész (-i)
      • Kimenő interfész (-o)
      • Küldő címe (-s)
      • Küldő portja (--sport)
      • Címzett címe (-d)
      • Címzett portja (--dport)
      • Művelet (-j)
       Feltételezzük, hogy a szabályban az opciók mindig ebben a sorrendben szerepelnek.
    • A táblázathoz lehessen új sort hozzáadni.1000|2 pont
    • A tábázat celláiban tárolt értékeket lehessen átírni.1 0000|2 pont
    • A táblázatból lehessen sort kitörölni.1 0000|2 pont
    • Legyen egy letöltés gomb, amire rákattintva a honlap egy fájlt készít a szabályokkal, és ezt letöltésre ajánlja fel.100 0000|2 pont
       Minden sor egy szabály. Ha a táblázat egy sorában valamelyik mező üres, a hozzá tartozó opció ne szerepeljen a szabályban.

    • Legyen opció ilyen szabályokat tartalmazó fájl feltöltésére. Ekkor:110 0000|2 pont
      • Legyen lehetőség a fájl kiválasztására.
      • Az oldal a táblázat korábbi tartalmát törölje.
      • A fájl tartalmát bontsátok sorokra, minden sort ellenőrizzetek és elemezzetek egy megfelelően megírt reguláris kifejezéssel.
      • Az illeszkedő sorokban lévő opciók alapján töltsétek fel a táblázatot. Ha egy sorban valamelyik opció nem szerepel, ott a táblázatban üres érték legyen.

    1101 1000|2 pont

Lazításként oldjátok meg, majd töltsétek fel az alábbi gondolatébresztő feladatokat is. Lehet, hogy éppen az itt szerzett bitpoint-ok vezetnek el benneteket egyenesen a döntőig.

Beküldhető feladatok:

  1. Az (x1,y1), (x2,y2),…,(xn,yn) valós értékpárok egy síkbeli, n csúcspontú konvex sokszög csúcspontjainak az óramutató járásával ellenkező irányú körüljárási sorrendben megadott koordinátái.
    • Számítsátok ki a sokszög kerületét!
    • Határozzátok meg a sokszög területét!
      Útmutató: Feltételezzük, hogy a sokszog az origot körbefogja. Az origót összekötve a csúcsokkal háromszögeket kapunk. Egy háromszög területét – ha az oldalakat a, b, c jelöli – a már megismert Heron képlettel számolhatjuk ki: T=Math.sqrt(s*(s-a)*(s-b)*(s-c)), ahol s=0,5*(a+b+c).

    10 0000|2 pont

  2. Számítsátok ki egy szám négyzetgyökét Newton módszerrel. A beolvasott szám legyen A. X1=A/2, Xn+1=(Xn+A/Xn)/2 ha n>=1. A számítást addig folytassátok, amíg |Xn+1-Xn|<0,0001. Az eredményt négy tizedes jeggyel jelenítsétek meg!

    1 0000|2 pont

« Előző | Lap eleje

Hivatkozások, felhasznált források

[1] Mozilla developer network: DOM (2013.11.13)

[2] CSS alapjai I. (2004.03.18)