{"id":627,"date":"2018-03-12T22:45:47","date_gmt":"2018-03-12T21:45:47","guid":{"rendered":"http:\/\/www.webotlet.hu\/?p=627"},"modified":"2018-03-12T22:59:04","modified_gmt":"2018-03-12T21:59:04","slug":"java-programozas-20-fajlkezeles-alapjai","status":"publish","type":"post","link":"https:\/\/www.webotlet.hu\/?p=627","title":{"rendered":"Java programoz\u00e1s 21. &#8211; F\u00e1jlkezel\u00e9s alapjai"},"content":{"rendered":"<h1>F\u00e1jlkezel\u00e9s, avagy dolgozzunk is m\u00e1r valamit<\/h1>\n<p>A k\u00f6z\u00e9piskolai programoz\u00e1s sor\u00e1n szinte minden esetben parancssoros fel\u00fcleten kereszt\u00fcl dolgozunk, ott tekintj\u00fck meg a kimeneteket, \u00e9s az esetleges interakci\u00f3kat (g\u00e9peld be a neved, adj meg egy sz\u00e1mot, stb) \u00e9s azon kereszt\u00fcl bonyol\u00edtjuk.<\/p>\n<p>Tanulm\u00e1nyaink sor\u00e1n egy nagyobb ugr\u00e1snak tekinthet\u0151 az, ha m\u00e1r k\u00fcls\u0151 adatokkal is tudunk dolgozni. Ett\u0151l kezdve nagyobb mennyis\u00e9g\u0171 adatot kezelhet\u00fcnk, rendszerezhet\u00fcnk, \u00f6sszetettebb feladatokat oldhatunk meg. Maga a f\u00e1jlkezel\u00e9si r\u00e9sze nem bonyolult, gyakorlatilag a f\u00e1jlokat kezel\u0151 utas\u00edt\u00e1sokat kell csak megtanulni, komolyabban gondolkodni sem kell rajta.<\/p>\n<p>Az \u00f6sszes ilyen folyamatot, ami a program \u00e9s a k\u00fclvil\u00e1g k\u00f6z\u00f6tti kommunik\u00e1ci\u00f3\u00e9rt felel\u0151s I\/O (input\/output) m\u0171veleteknek nevezz\u00fck. Ezt a kommunik\u00e1ci\u00f3t a Java adatfolyamokon, m\u00e1s n\u00e9ven Stream-eken kereszt\u00fcl val\u00f3s\u00edtja meg. Az adatfolyamok nagy r\u00e9sz\u00e9t \u00fagy kell elk\u00e9pzelni, mint egy cs\u00f6vet egy csappal, amelyet meg kell nyitni ahhoz, hogy \u00e1thaladhasson rajta az, amit sz\u00e1ll\u00edt. Vannak azonban olyanok is, melyeket ett\u0151l az\u00e9rt egyszer\u0171bb haszn\u00e1lni.<\/p>\n<h2>Konzol<\/h2>\n<p>Kezd\u0151k\u00e9nt kiz\u00e1r\u00f3lag konzolon kereszt\u00fcl kommunik\u00e1lunk a programunkkal. A konzol kezel\u00e9s\u00e9re a Java h\u00e1rom olyan adatfolyamot biztos\u00edt, melyeket nem kell nyitni-z\u00e1rni ahhoz, hogy kommunik\u00e1lhassunk rajta kereszt\u00fcl, ezek a Standard Stream-ek. Ezekb\u0151l a Java a k\u00f6vetkez\u0151ket biztos\u00edtja sz\u00e1munkra:<\/p>\n<ol>\n<li>Standard kimenet: System.out<\/li>\n<li>Standard bemenet: System.in<\/li>\n<li>Standard hiba: System.err<\/li>\n<\/ol>\n<p>Az els\u0151 onnan lehet ismer\u0151s, hogy szinte a kezdetekt\u0151l ezt haszn\u00e1ltuk ki\u00edrat\u00e1sra, vagyis m\u00e1r akkor is Stream-et haszn\u00e1ltunk. A m\u00e1sodik az <a title=\"Java programoz\u00e1s 18. \u2013 Adatbek\u00e9r\u00e9s\" href=\"http:\/\/www.webotlet.hu\/?p=629\">Adatbek\u00e9r\u00e9s<\/a> t\u00e9mak\u00f6rb\u0151l lehet ismer\u0151s. Amikor a felhaszn\u00e1l\u00f3val adatokat szeretn\u00e9nk beg\u00e9peltetni, akkor a Scanner oszt\u00e1lynak ezt kellett odaadni, ez alap\u00e9rtelmezetten a billenty\u0171zetet jelenti a konzolban. A harmadik szint\u00e9n egy kimeneti csatorna, de annak egy speci\u00e1lis fajt\u00e1ja. Ez is gyakorlatilag egy olyan ki\u00edrat\u00e1st v\u00e9gez el, mint a System.out, de ezt csak hiba\u00fczenet ki\u00edrat\u00e1sra szok\u00e1s haszn\u00e1lni. A gyakorlati haszna tal\u00e1n annyi, hogy bizonyos fejleszt\u0151i k\u00f6rnyezetek (Eclipse), megk\u00fcl\u00f6nb\u00f6ztet\u0151 v\u00f6r\u00f6s sz\u00ednnel emelik ki az ebbe \u00edrt \u00fczeneteket, ezzel is nyomat\u00e9kos\u00edtva, hogy ez egy hiba\u00fczenet.<\/p>\n<h2>F\u00e1jlkezel\u00e9s, mint kock\u00e1zat<\/h2>\n<p>A Java nyelvben a f\u00e1jlkezel\u00e9s is Stream-eken kereszt\u00fcl val\u00f3sul meg. Ezeket azonban csak akkor haszn\u00e1lhatjuk, ha a programunk elej\u00e9n import\u00e1ljuk a java.io oszt\u00e1lyt, mely ezeket a Stream-eket tartalmazza. A programunk elej\u00e9t teh\u00e1t kezdj\u00fck ezzel:<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">import java.io.*;<\/pre>\n<p>Ez nem csak a Stream-ek haszn\u00e1lat\u00e1hoz sz\u00fcks\u00e9ges k\u00f3dokat tartalmazza, hanem a hibakezel\u00e9s megfelel\u0151 oszt\u00e1lyait is. A f\u00e1jlkezel\u00e9s mindig rizik\u00f3s. Nincs meg a f\u00e1jl. Vagy csak a hely\u00e9t adtuk meg rosszul. Esetleg a nev\u00e9t \u00edrtuk el. Pont megd\u00f6gl\u00f6tt az adathordoz\u00f3, ahol egy\u00e9bk\u00e9nt j\u00f3 helyen \u00e9s j\u00f3 n\u00e9ven megtal\u00e1ljuk. Att\u00f3l f\u00fcggetlen\u00fcl, hogy f\u00e1jlokat olvasni vagy \u00edrni akarunk, mindenk\u00e9ppen egy kiv\u00e9telkezel\u0151 szerkezettel kell megoldani. Formailag ez a k\u00f6vetkez\u0151k\u00e9pp n\u00e9z ki:<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\ntry\r\n{\r\n  \/* Itt megk\u00eds\u00e9rl\u00fcnk v\u00e9grehajtani valami kock\u00e1zatos dolgot,\r\n   * ami lehets\u00e9ges, hogy nem m\u0171k\u00f6dik, ak\u00e1r rajtunk k\u00edv\u00fcl\u00e1ll\u00f3\r\n   * okok miatt.\r\n   *\/\r\n}\r\ncatch( IOException e )\r\n{\r\n  \/* Ha megt\u00f6rt\u00e9nt a baj, akkor a v\u00e9grehajt\u00e1s a catch \u00e1gra ugrik,\r\n   * de a programunk nem \u00e1ll le fut\u00e1si hiba\u00fczenettel, hanem itt\r\n   * megadhatjuk, hogy hiba eset\u00e9n mi t\u00f6rt\u00e9njen.\r\n   *\/\r\n}\r\nfinally\r\n{\r\n  \/* V\u00e9gezet\u00fcl ak\u00e1r sikeres volt a v\u00e9grehajt\u00e1s a try \u00e1gon, ak\u00e1r\r\n   * hib\u00e1s a catch \u00e1gon, v\u00e9g\u00fcl mindenk\u00e9pp ide jutunk. Ide\r\n   * helyezhetj\u00fck azokat az utas\u00edt\u00e1sokat, melyeket hib\u00e1tlan \u00e9s\r\n   * hib\u00e1s fut\u00e1s eset\u00e9n is sz\u00fcks\u00e9ges v\u00e9grehajtani. P\u00e9ld\u00e1ul a\r\n   * f\u00e1jlkezel\u00e9s ak\u00e1r sikeres, ak\u00e1r sikertelen volt, a f\u00e1jlt nem\r\n   * hagyhatjuk nyitva, itt lez\u00e1rhatjuk. Maga a lez\u00e1r\u00e1s is\r\n   * egy\u00e9bk\u00e9nt kock\u00e1zattal j\u00e1r, vagyis ide is egy try-catch\r\n   * szerkezet kell, csak hogy ne legyen egyszer\u0171.\r\n   * Ez az \u00e1g azonban nem k\u00f6telez\u0151!\r\n   *\/\r\n}\r\n<\/pre>\n<p>N\u00e9zz\u00fcnk akkor p\u00e9ld\u00e1kat, milyen f\u00e1jlkezel\u00e9si feladatokkal kell megk\u00fczden\u00fcnk. A feladatok sor\u00e1n sz\u00f6veges \u00e1llom\u00e1nyokat fogunk kezelni: beolvassuk, m\u00f3dos\u00edtjuk azokat, hozz\u00e1f\u0171z\u00fcnk, besz\u00farunk sorokat. A f\u00e1jlokat egyel\u0151re a try \u00e1gban z\u00e1rjuk majd le, a finally lehet\u0151s\u00e9get hanyagoljuk.<\/p>\n<h2>RandomAccessFile<\/h2>\n<p>A f\u00e1jlkezel\u00e9shez sokf\u00e9le el\u0151re meg\u00edrt oszt\u00e1ly ny\u00fajt seg\u00edts\u00e9get, mi a RandomAccessFile oszt\u00e1lyt fogjuk haszn\u00e1lni. Ez lehet\u0151s\u00e9get ny\u00fajt arra, hogy a f\u00e1jlban tetsz\u0151leges helyre pozicion\u00e1ljunk, de az\u00e9rt p\u00e1r dologra majd figyelni kell.<\/p>\n<p>Az oszt\u00e1ly haszn\u00e1lata meglehet\u0151sen egyszer\u0171. A try-catch szerkezetre mindenk\u00e9pp sz\u00fcks\u00e9g\u00fcnk van, err\u0151l az el\u0151z\u0151 r\u00e9szben l\u00e1thatt\u00e1l p\u00e9ld\u00e1t, de akkor most kicsit konkr\u00e9tabban n\u00e9zz\u00fck meg ezt. A finally \u00e1ggal majd k\u00e9s\u0151bb foglalkozunk.<\/p>\n<pre class=\"brush: java; gutter: true; highlight: [1,7,8,12,14,18]; title: ; notranslate\" title=\"\">\r\nimport java.io.*;\r\n\r\npublic class Fajlkezelesalapok\r\n{\r\n  public static void main(String&#x5B;] args)\r\n  {\r\n    RandomAccessFile raf;\r\n    String sor;\r\n\r\n    try\r\n    {\r\n      raf = new RandomAccessFile(&quot;nevek.txt&quot;,&quot;r&quot;);\r\n\r\n      raf.close();\r\n    }\r\n    catch( IOException e )\r\n    {\r\n      System.err.println(&quot;HIBA&quot;);\r\n    }\r\n  }\r\n}\r\n<\/pre>\n<p>L\u00e1ssuk akkor a kiemelt sorokban a l\u00e9nyeget:<\/p>\n<ul>\n<li>1 &#8211; Import\u00e1ljuk a megfelel\u0151 oszt\u00e1lyokat (ebben benne vannak a kiv\u00e9tel kezel\u0151 oszt\u00e1lyok \u00e9s a RandomAccessFile is).<\/li>\n<li>7 &#8211; L\u00e9trehozunk egy v\u00e1ltoz\u00f3t raf n\u00e9ven a RandomAccessFile oszt\u00e1lynak, mert ett\u0151l kezdve ezzel hivatkozhatunk r\u00e1.<\/li>\n<li>8 &#8211; A majdan beolvas\u00e1sra ker\u00fcl\u0151 sorokat valamilyen Stringben t\u00e1rolni kell. Nem az \u00f6sszeset, mindig csak az altu\u00e1list.<\/li>\n<li>12 &#8211; Itt hozunk l\u00e9tre egy \u00faj objektumot a RandomAccessFile oszt\u00e1lyb\u00f3l, vagyis megh\u00edvjuk a konstruktor\u00e1t. K\u00e9t param\u00e9tert v\u00e1r, az egyik a f\u00e1jl el\u00e9r\u00e9si \u00fatvonala, a m\u00e1sik, hogy milyen m\u00f3dban (olvas\u00e1s-\u00edr\u00e1s) nyitjuk meg a f\u00e1jlt. Ha a f\u00e1jl a forr\u00e1sk\u00f3dunk mellett van (NetBeans eset\u00e9n pedig a projekt gy\u00f6k\u00e9rk\u00f6nyvt\u00e1r\u00e1ban), akkor el\u00e9g csak a f\u00e1jln\u00e9v. A kiterjeszt\u00e9s is kell! A megnyit\u00e1si m\u00f3d jelen esetben read &#8220;r&#8221;, mert m\u00f3dos\u00edtani nem akarjuk.<\/li>\n<li>14 &#8211; Miut\u00e1n a f\u00e1jllal megtett\u00fck, amit akartunk, le kell z\u00e1rni.<\/li>\n<li>18 &#8211; A System.err kimenettel az a gondom, hogy sokszor a kimenetben nem j\u00f3 helyen jelenik meg az \u00e1ltala kik\u00fcld\u00f6tt ki\u00edrat\u00e1s, \u00edgy ez zavar\u00f3 lehet.\u00a0 Ett\u0151l kezdve itt is a System.out-ot fogom haszn\u00e1lni a k\u00e9s\u0151bbi p\u00e9ld\u00e1kban.<\/li>\n<\/ul>\n<p>Ez az alapja annak, hogy egy f\u00e1jlt kezelni tudjunk. Ha m\u00f3dos\u00edtani szeretn\u00e9nk a tartalm\u00e1t, akkor &#8220;rw&#8221; m\u00f3dban kell megnyitni. A sorok beolvas\u00e1s\u00e1hoz mindenk\u00e9pp ciklusra van sz\u00fcks\u00e9g\u00fcnk, hiszen minden egyes sort azonos m\u00f3don olvasunk be. A haszn\u00e1lt ciklus a 3 tanult fajt\u00e1b\u00f3l b\u00e1rmelyik lehet. Ez a gyakorlatban a tapasztalatlan tanul\u00f3kn\u00e1l ink\u00e1bb gondot szokott okozni, de p\u00e1r sablon megtanul\u00e1s\u00e1val b\u00e1rmilyen sz\u00f6veges f\u00e1jlt kezelni lehet, teh\u00e1t tess\u00e9k ezt is megtanulni!<\/p>\n<h2>F\u00e1jl beolvas\u00e1sa<\/h2>\n<p>A list\u00e1t, mint szerkezetet nagyon j\u00f3l lehet haszn\u00e1lni a f\u00e1jlkezel\u00e9s sor\u00e1n, de most az\u00e9rt, hogy \u00e9rts\u00fck, mi\u00e9rt fognak lassan korl\u00e1tozni a t\u00f6mb\u00f6k, vel\u00fck kezdj\u00fck a feladatok megold\u00e1s\u00e1t. A f\u00e1jl sorait minden esetben mint karakterl\u00e1ncokat olvassuk be. Ha ezek egy\u00e9bk\u00e9nt sz\u00e1mokat tartalmaznak, azokat \u00e1t kell majd alak\u00edtanunk. Ha csak a nyers beolvasott sorokat akarjuk t\u00e1rolni, akkor ehhez egy String t\u00f6mbre van sz\u00fcks\u00e9g\u00fcnk.<\/p>\n<p>Az els\u0151 gond teh\u00e1t az szokott lenni a f\u00e1jlkezel\u00e9s sor\u00e1n, hogy a beolvasott \u00e1llom\u00e1nyt valahol t\u00e1rolni kell. Hogyan? Soronk\u00e9nt? A sorokat m\u00e9g tov\u00e1bb bonthatjuk? Ne szaladjunk ennyire el\u0151re, kezdj\u00fck az elej\u00e9n.<\/p>\n<p>K\u00fcl\u00f6nb\u00f6z\u0151 szerkezet\u0171 forr\u00e1sok eset\u00e9n beolvas\u00e1s szempontj\u00e1b\u00f3l az al\u00e1bbi esetek lehets\u00e9gesek:<\/p>\n<ol>\n<li>El\u0151re tudjuk, h\u00e1ny sorb\u00f3l \u00e1ll a f\u00e1jl<\/li>\n<li>Nem tudjuk, h\u00e1ny sorb\u00f3l \u00e1ll a f\u00e1jl, de az els\u0151 sorban megtal\u00e1ljuk a sorok darabsz\u00e1m\u00e1t<\/li>\n<li>Nem tudjuk, h\u00e1ny sorb\u00f3l \u00e1ll a f\u00e1jl<\/li>\n<\/ol>\n<p>Az els\u0151 eset a legegyszer\u0171bb, hiszen azonnal l\u00e9trehozhatunk egy sorok sz\u00e1m\u00e1nak megfelel\u0151 m\u00e9ret\u0171 t\u00f6mb\u00f6t, \u00e9s a beolvasott sorokat elt\u00e1roljuk.<\/p>\n<p>A m\u00e1sodik eset csak annyival bonyolultabb, hogy az els\u0151 sort k\u00fcl\u00f6n kell beolvasnunk, majd az ott kapott \u00e9rt\u00e9knek megfelel\u0151en kell a t\u00f6mb m\u00e9ret\u00e9t be\u00e1ll\u00edtani.<\/p>\n<p>A harmadik esetben nincs mese, sz\u00e1molnunk kell, hiszen a t\u00f6mb m\u00e9ret\u00e9t el\u0151re kell be\u00e1ll\u00edtanunk, de fogalmunk sincs, h\u00e1ny sorb\u00f3l \u00e1ll a f\u00e1jlunk. Ekkor k\u00e9tszer olvassuk be a f\u00e1jlt. Egyszer az\u00e9rt, hogy megsz\u00e1moljuk, h\u00e1ny sorb\u00f3l \u00e1ll. Ekkor a t\u00f6mbm\u00e9retet be\u00e1ll\u00edtva beolvassuk a f\u00e1jlt \u00fajra, ekkor m\u00e1r az\u00e9rt, hogy elt\u00e1roljuk a tartalm\u00e1t.<\/p>\n<p>L\u00e1ssuk, hogy n\u00e9z ki ez a gyakorlatban. Ugyanazt a feladatot fogom 3 k\u00fcl\u00f6nf\u00e9le ciklussal megoldani. A m\u00e1r ismert dolgokat nem emelem ki \u00fajra, de a l\u00e9nyegi dolgokat igen.<\/p>\n<h4>El\u0151re tudjuk a f\u00e1jl adatsorainak sz\u00e1m\u00e1t<\/h4>\n<p>Adott egy 6 keresztnevet tartalmaz\u00f3 sz\u00f6vegf\u00e1jl. Olvassuk be a tartalm\u00e1t, t\u00e1roljuk el, \u00e9s \u00edrjuk ki a k\u00e9perny\u0151re!<\/p>\n<h5>Megold\u00e1s while ciklussal<\/h5>\n<pre class=\"brush: java; gutter: true; highlight: [9,15,16,18,19,20,21,22,23,32,33,34,35]; title: ; notranslate\" title=\"\">\r\nimport java.io.*;\r\n\r\npublic class Fajlkezelesalapok\r\n{\r\n  public static void main(String&#x5B;] args)\r\n  {\r\n    RandomAccessFile raf;\r\n    String sor;\r\n    String&#x5B;] nevek = new String&#x5B;6];\r\n\r\n    try\r\n    {\r\n      raf = new RandomAccessFile(&quot;nevek.txt&quot;,&quot;r&quot;);\r\n\r\n      int db = 0;\r\n      sor = raf.readLine();\r\n\r\n      while( sor != null )\r\n      {\r\n        nevek&#x5B;db] = sor;\r\n        db++;\r\n        sor = raf.readLine();\r\n      }\r\n      \r\n      raf.close();\r\n    }\r\n    catch( IOException e )\r\n    {\r\n      System.out.println(&quot;HIBA&quot;);\r\n    }\r\n\r\n    for( String str : nevek )\r\n    {\r\n      System.out.println(str);\r\n    }\r\n  }\r\n}\r\n<\/pre>\n<p>N\u00e9zz\u00fck akkor a kiemelt r\u00e9szeket:<\/p>\n<ul>\n<li>9 &#8211; Mivel el\u0151re tudjuk, hogy 6 nevet tartalmaz a f\u00e1jl, ekkora t\u00f6mb\u00f6t hozunk l\u00e9tre t\u00e1rolni azokat.<\/li>\n<li>15 &#8211; Egy sz\u00e1ml\u00e1l\u00f3, mely majd az aktu\u00e1lisan beolvasott sor t\u00f6mbbeli hely\u00e9t adja majd meg. Null\u00e1r\u00f3l indul term\u00e9szetesen, mint a t\u00f6mb\u00f6k indexel\u00e9se.<\/li>\n<li>16 &#8211; Beolvasunk egy sort, \u00e9s elt\u00e1roljuk a sor nev\u0171 String t\u00edpus\u00fa v\u00e1ltoz\u00f3ban. <strong>Fontos, hogy a readLine() met\u00f3dus, mindig eg\u00e9sz sort olvas be (a sorv\u00e9gjelig), \u00e9s az \u00fagynevezett f\u00e1jlmutat\u00f3 (hogy \u00e9ppen hol tartok a f\u00e1jlban) automatikusan a k\u00f6vetkez\u0151 sor elej\u00e9re ker\u00fcl, a sor hossz\u00e1t\u00f3l f\u00fcggetlen\u00fcl.<\/strong><\/li>\n<li>18-23 &#8211; R\u00f6gt\u00f6n azzal kezden\u00e9m, hogy a ciklus fut\u00e1si felt\u00e9tele azt jelenti, hogy a beolvasott sor nem <strong>null<\/strong> \u00e9rt\u00e9k. Null \u00e9rt\u00e9ket akkor olvashatunk, ha a f\u00e1jl v\u00e9g\u00e9n \u00e1llunk. Teh\u00e1t ha nem vagyunk a f\u00e1jl v\u00e9g\u00e9n, akkor mehet\u00fcnk tov\u00e1bb. L\u00e1thatod, hogy a ciklus minden esetben azzal kezdi, hogy a nevek t\u00f6mb db-odik hely\u00e9re berakja a beolvasott sor. A db v\u00e1ltoz\u00f3 itt egy mutat\u00f3k\u00e9nt funkcion\u00e1l, ami minden esetben azt mutatja, hogy a t\u00f6mbben hol tal\u00e1lhat\u00f3 a k\u00f6vetkez\u0151 \u00fcres hely. Mivel most erre az \u00fcres helyre betett\u00fcnk egy elemet, a mutat\u00f3t a k\u00f6vetkez\u0151 \u00fcres hely index\u00e9re \u00e1ll\u00edtjuk (megn\u00f6velt\u00fck). Ha ez megt\u00f6rt\u00e9nt, beolvassuk a k\u00f6vetkez\u0151 sort. Persze ha ez a sor lesz a f\u00e1jl v\u00e9ge, akkor ezt m\u00e1r nem t\u00e1roljuk el tessz\u00fck be a t\u00f6mbbe, mert a ciklus fut\u00e1si felt\u00e9tele nem fog teljes\u00fclni. Ilyenkor a db v\u00e1ltoz\u00f3 egy nem l\u00e9tez\u0151 helyre mutat (a t\u00f6mb\u00f6n k\u00edv\u00fcl), ami val\u00f3j\u00e1ban a t\u00f6mb m\u00e9rete lesz.<\/li>\n<li>25-28 &#8211; Ki\u00edrjuk a t\u00f6mb elemeit egym\u00e1s al\u00e1.<\/li>\n<\/ul>\n<h5>Megold\u00e1s for ciklussal<\/h5>\n<pre class=\"brush: java; gutter: true; highlight: [15,16]; title: ; notranslate\" title=\"\">\r\nimport java.io.*;\r\n\r\npublic class Fajlkezelesalapok\r\n{\r\n  public static void main(String&#x5B;] args)\r\n  {\r\n    RandomAccessFile raf;\r\n    String sor;\r\n    String&#x5B;] nevek = new String&#x5B;6];\r\n\r\n    try\r\n    {\r\n      raf = new RandomAccessFile(&quot;nevek.txt&quot;,&quot;r&quot;);\r\n\r\n      int db = 0;\r\n      for( sor = raf.readLine(); sor != null; sor = raf.readLine() )\r\n      {\r\n        nevek&#x5B;db] = sor;\r\n        db++;\r\n      }\r\n      \r\n      raf.close();\r\n    }\r\n    catch( IOException e )\r\n    {\r\n      System.out.println(&quot;HIBA&quot;);\r\n    }\r\n\r\n    for( String str : nevek )\r\n    {\r\n       System.out.println(str);\r\n    }\r\n  }\r\n}\r\n<\/pre>\n<ul>\n<li>15 &#8211; Egy ugyanolyan sz\u00e1ml\u00e1l\u00f3, mint az el\u0151z\u0151 esetben.<\/li>\n<li>16 &#8211; A for ciklust most el\u00e9g \u00e9rdekesen haszn\u00e1lom. El\u0151sz\u00f6r is, nincs klasszikus ciklusv\u00e1ltoz\u00f3. Ok\u00e9, van egy db, de azt most nem a ciklus kezeli. S\u0151t, m\u00e9g a sor v\u00e1ltoz\u00f3t sem a ciklusban deklar\u00e1ltam, hanem el\u0151tte. Majd k\u00e9s\u0151bb megl\u00e1tod, mi\u00e9rt. Sz\u00f3val a ciklusfej inicializ\u00e1l\u00f3 r\u00e9sz\u00e9ben beolvasok egy sort. Fut\u00e1si felt\u00e9telk\u00e9nt megvizsg\u00e1lom, hogy a sor az null \u00e9rt\u00e9k-e. Ha nem, akkor a ciklusmagban elt\u00e1rolom a beolvasott sort a while p\u00e9ld\u00e1ban ismertetett m\u00f3don (a db v\u00e1ltoz\u00f3val jelzett \u00fcres helyre), majd a ciklus n\u00f6vekm\u00e9nyes r\u00e9sz\u00e9ben beolvasom a k\u00f6vetkez\u0151 sort.<\/li>\n<\/ul>\n<h5>Megold\u00e1s do-while ciklussal<\/h5>\n<pre class=\"brush: java; gutter: true; title: ; notranslate\" title=\"\">\r\nimport java.io.*;\r\n\r\npublic class Fajlkezelesalapok\r\n{\r\n  public static void main(String&#x5B;] args)\r\n  {\r\n    RandomAccessFile raf;\r\n    String sor;\r\n    String&#x5B;] nevek = new String&#x5B;6];\r\n\r\n    try\r\n    {\r\n      raf = new RandomAccessFile(&quot;nevek.txt&quot;,&quot;r&quot;);\r\n      \r\n      int db = 0;\r\n      sor = raf.readLine();\r\n      do\r\n      {\r\n        nevek&#x5B;db] = sor;\r\n        db++;\r\n        sor = raf.readLine();\r\n      }\r\n      while( sor != null );\r\n      \r\n      raf.close();\r\n    }\r\n    catch( IOException e )\r\n    {\r\n      System.out.println(&quot;HIBA&quot;);\r\n    }\r\n\r\n    for( String str : nevek )\r\n    {\r\n      System.out.println(str);\r\n    }\r\n  }\r\n}\r\n<\/pre>\n<p>Ezt a megold\u00e1st nem is fejten\u00e9m ki r\u00e9szletesen, hiszen csak ismert dolgokat l\u00e1thatsz benne. A h\u00e1rom megold\u00e1s k\u00f6z\u00fcl viszont az egyik s\u00e1nt\u00edt, ez\u00e9rt nem is szeretem, ha \u00e1ltal\u00e1nos megold\u00e1s t\u00edpusk\u00e9nt azt haszn\u00e1lj\u00e1k. Melyik akadhat ki a h\u00e1romb\u00f3l \u00e9s mikor? Gondolkodj el ezen.<\/p>\n<h4>A f\u00e1jl sorainak sz\u00e1m\u00e1t az els\u0151 sor tartalmazza<\/h4>\n<p>Eml\u00edtettem azt, hogy h\u00e1rom alapeset van akkor, ha el szeretn\u00e9nk t\u00e1rolni a beolvasott f\u00e1jl tartalm\u00e1t. Az els\u0151n m\u00e1r t\u00fal vagyunk, vagyis valami okn\u00e1l fogva pontosan tudtuk, hogy h\u00e1ny sorb\u00f3l \u00e1ll a f\u00e1jl, \u00edgy k\u00f6nny\u0171 dolgunk van.<\/p>\n<p>N\u00e9ha nem ennyire j\u00f3 fejek, de annyira az\u00e9rt igen, hogy a f\u00e1jl els\u0151 sor\u00e1ba oda\u00edrj\u00e1k a megfejt\u00e9st. Mondjuk \u00edgy n\u00e9z ki a f\u00e1jlunk tartalma:<\/p>\n<p>6<br \/>\nBela<br \/>\nJozsef<br \/>\nAnna<br \/>\nPeter<br \/>\nEva<br \/>\nJolan<\/p>\n<p>Az els\u0151 sorban ott van a val\u00f3di adatokat tartalmaz\u00f3 sorok sz\u00e1ma. Nosza, haszn\u00e1ljuk. Az el\u0151z\u0151leg felsorolt h\u00e1rom lehet\u0151s\u00e9g k\u00f6z\u00fcl ez a 2. eset, vagyis itt a f\u00e1jl els\u0151 sor\u00e1ban az a sz\u00e1m tal\u00e1lhat\u00f3, ami a t\u00e1roland\u00f3 adatok t\u00f6mbj\u00e9nek m\u00e9ret\u00e9t jelenti.<\/p>\n<pre class=\"brush: java; gutter: true; highlight: [3,9,11,13,28]; title: ; notranslate\" title=\"\">\r\nRandomAccessFile raf;\r\nString sor;\r\nString&#x5B;] nevek = null; \/\/ m\u00e9g nem tudjuk h\u00e1ny nev\u00fcnk lesz\r\n\r\ntry\r\n{\r\n  raf = new RandomAccessFile(&quot;nevek.txt&quot;,&quot;rw&quot;);\r\n\r\n  int db = Integer.parseInt( raf.readLine() );\r\n\/\/ most m\u00e1r tudjuk, fel is haszn\u00e1ljuk gyorsan\r\n  nevek = new String&#x5B;db];\r\n\r\n  db = 0;\r\n  for( sor = raf.readLine(); sor != null; sor = raf.readLine() )\r\n  {\r\n    nevek&#x5B;db] = sor;\r\n    db++;\r\n  }\r\n\r\n  raf.close();\r\n}\r\ncatch( IOException e )\r\n{\r\n  System.out.println(&quot;HIBA&quot;);\r\n}\r\n\r\n\/\/ elemek ki\u00edr\u00e1sa, stb...\r\nfor( String str : nevek )\r\n{\r\n  System.out.println(str);\r\n}\r\n\/\/ ....\r\n\/\/ ....\r\n<\/pre>\n<ul>\n<li>3 &#8211; <strong>Nagyon fontos sor!<\/strong> A t\u00f6mb\u00f6t a f\u00e1jl elej\u00e9n deklar\u00e1ltam a try-catch szerkezeten k\u00edv\u00fcl, pontosabban el\u0151tte. Mindez az\u00e9rt fontos, mert ezt a t\u00f6mb\u00f6t a f\u00e1jlkezel\u00e9s lez\u00e1r\u00e1sa ut\u00e1n is szeretn\u00e9m, s\u0151t, igaz\u00e1n akkor szeretn\u00e9m haszn\u00e1lni! A f\u00e1jlkezel\u00e9s csak az\u00e9rt kell, hogy legyenek adataim, amivel ut\u00e1na dolgozhatok. Mi lenne ott akkor, ha a t\u00f6mb nem kapna kezd\u0151\u00e9rt\u00e9ket? Mondjuk a 3-as sor ut\u00e1n csak ennyi szerepelne:\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">String&#x5B;] nevek;<\/pre>\n<p>Mi a helyzet akkor, ha egy v\u00e1ltoz\u00f3nak nincs kezd\u0151\u00e9rt\u00e9ke? Addig nem haszn\u00e1lhatom. A 28-as sorban bizony haszn\u00e1lni szeretn\u00e9m a ki\u00edrat\u00e1shoz. Hib\u00e1t is okoz, r\u00e1ad\u00e1sul szintaktikai hib\u00e1t. Addig el sem indulhat a programom, am\u00edg ez itt van. De mi\u00e9rt van itt? Hiszen a try \u00e1gban \u00fagyis megadom a t\u00f6mb m\u00e9ret\u00e9t! Az addig rendben, de a f\u00e1jlkezel\u00e9s kock\u00e1zat. Semmi nem garant\u00e1lja, hogy a f\u00e1jl ott lesz, j\u00f3 n\u00e9ven, \u00e9ppen nem haszn\u00e1lja valaki stb. Vagyis <strong>lehet, hogy nem a try hanem a catch \u00e1g fog lefutni, \u00e9s a t\u00f6mbnek nem lesz kezd\u0151\u00e9rt\u00e9ke!<\/strong> Vagyis a ki\u00edrat\u00e1skor mindenk\u00e9ppen hib\u00e1t fog jelezni! A program persze el\u0151re nem tudhatja, hogy hib\u00e1s lesz-e a beolvas\u00e1s, vagy sem, neki az a l\u00e9nyeg, hogy kezd\u0151\u00e9rt\u00e9k n\u00e9lk\u00fcli v\u00e1ltoz\u00f3t nem haszn\u00e1lhatunk!<\/li>\n<li>9 &#8211; Mivel tudom, hogy ott van a f\u00e1jl elej\u00e9n a val\u00f3di sorok sz\u00e1ma (le\u00edrta a feladat, megmondt\u00e1k, meg\u00e1lmodtam, stb), ez\u00e9rt beolvasom az els\u0151 sort. Ennek eredm\u00e9ny\u00e9t azonnal sz\u00e1mm\u00e1 alak\u00edtottam, ez jelenti majd a t\u00f6mb\u00f6m m\u00e9ret\u00e9t.<\/li>\n<li>11 &#8211; R\u00f6gt\u00f6n be is \u00e1ll\u00edtom a megfelel\u0151 m\u00e9retet. De azzal, hogy az els\u0151 sort beolvastam, a f\u00e1jlmutat\u00f3 m\u00e1ris \u00e1tker\u00fclt a k\u00f6vetez\u0151 sor elej\u00e9re. Mi\u00e9rt j\u00f3 ez? Mert a for ciklussal t\u00f6rt\u00e9n\u0151 feldolgoz\u00e1s m\u00e1r csak a val\u00f3di adatsorokat olvassa be.<\/li>\n<li>13 &#8211; A db v\u00e1ltoz\u00f3t most null\u00e1zom, mert ett\u0151l kezdve ez m\u00e1r nem megsz\u00e1mol (nincs is r\u00e1 sz\u00fcks\u00e9g), hanem mutat\u00f3k\u00e9nt ism\u00e9t a t\u00f6mbben l\u00e9v\u0151 \u00fcres helyet mutatja beolvasott adatok sz\u00e1m\u00e1ra.<\/li>\n<\/ul>\n<p>Ne felejts\u00fck el ezt a momentumot, hogy a readLine() beolvasott egy sort, \u00e9s a mutat\u00f3 a k\u00f6vetkez\u0151 sor elej\u00e9re ker\u00fclt. Feljebb m\u00e1r emlegettem, ki is emeltem ezt! <strong>A readLine() met\u00f3dus ak\u00e1r arra is haszn\u00e1lhat\u00f3, hogy sorokat ugorjunk \u00e1t a f\u00e1jlban feldolgoz\u00e1s n\u00e9lk\u00fcl. Ez m\u00e9g hasznos lesz a k\u00e9s\u0151bbiekben!<\/strong><\/p>\n<h4>Nem tudom h\u00e1ny sorb\u00f3l \u00e1ll a f\u00e1jl<\/h4>\n<p>Itt semmit nem tudok a f\u00e1jlr\u00f3l, legfeljebb annyit, hogy nem tartalmaz t\u00f6bb sort, mint mondjuk 100. Ilyenkor mit tehetek?<\/p>\n<ol>\n<li>L\u00e9trehozok egy 100 elem\u0171 t\u00f6mb\u00f6t, beolvasok mindent, \u00e9s megjegyzem egy sz\u00e1ml\u00e1l\u00f3ban, hogy h\u00e1ny val\u00f3di elemet tartalmaz a t\u00f6mb. Na ne&#8230;<\/li>\n<li><strong>Megsz\u00e1molom a sorokat, majd egy pont akkora t\u00f6mb\u00f6t hozok l\u00e9tre, amibe \u00e9ppen belef\u00e9r annyi sor, \u00edgy a t\u00f6mb\u00f6m m\u00e9rete a val\u00f3di sorok sz\u00e1m\u00e1t jelenti. Azt\u00e1n beolvasok mindent \u00e9s elt\u00e1rolom.<\/strong><\/li>\n<li><a title=\"Java programoz\u00e1s 19. \u2013 ArrayList\" href=\"http:\/\/www.webotlet.hu\/?p=775\">List\u00e1t<\/a> haszn\u00e1lok. De csak akkor, ha t\u00f6mb\u00f6kb\u0151l m\u00e1r profi vagyok!<\/li>\n<\/ol>\n<p>Am\u00edg nem ismered a list\u00e1kat, a megold\u00e1s menete a kiemelt algoritmus szerint t\u00f6rt\u00e9nik. L\u00e1ssuk ezt hogyan lehet megoldani.<\/p>\n<pre class=\"brush: java; gutter: true; highlight: [3,12,14,15,17]; title: ; notranslate\" title=\"\">\r\nRandomAccessFile raf;\r\nString sor;\r\nString&#x5B;] nevek = null; \/\/ m\u00e9g nem tudjuk h\u00e1ny nev\u00fcnk lesz\r\n\r\ntry\r\n{\r\n  raf = new RandomAccessFile(&quot;nevek.txt&quot;,&quot;rw&quot;);\r\n\r\n  int db = 0;\r\n  for( sor = raf.readLine(); sor != null; sor = raf.readLine() )\r\n  {\r\n    db++;\r\n  }\r\n  nevek = new String&#x5B;db];\r\n  raf.seek(0);\r\n\r\n  db = 0;\r\n  for( sor = raf.readLine(); sor != null; sor = raf.readLine() )\r\n  {  \r\n    nevek&#x5B;db] = sor;\r\n    db++;\r\n  }\r\n\r\n  raf.close();\r\n}\r\ncatch( IOException e )\r\n\/\/ ....\r\n\/\/ ....\r\n<\/pre>\n<ul>\n<li>3 &#8211; M\u00e1r ismer\u0151s, ugye? El ne felejtsd! B\u00e1r \u00fagyis hamar \u00e9szreveszed, hogy nem m\u0171k\u00f6dik a program \ud83d\ude42<\/li>\n<li>12 &#8211; Az\u00e9rt megyek v\u00e9gig a f\u00e1jlon, hogy megsz\u00e1moljam, h\u00e1ny sorb\u00f3l \u00e1ll. Ah\u00e1nyszor lefut a ciklus, annyi sorb\u00f3l \u00e1llt \u00e9s n\u00f6velgettem a sz\u00e1ml\u00e1l\u00f3m.<\/li>\n<li>14 &#8211; Most m\u00e1r tudom, mekkora t\u00f6mb kell. Itt a db a t\u00f6mbm\u00e9retet jelenti! Ez\u00e9rt sz\u00e1moltuk meg a sorokat, hogy pont akkora t\u00f6mb\u00fcnk legyen, amekkor\u00e1ra \u00e9ppen sz\u00fcks\u00e9g\u00fcnk van.<\/li>\n<li>15 &#8211; Megint v\u00e9gig akarom majd olvasni a f\u00e1jlt, mert el\u0151sz\u00f6r csak a sorait sz\u00e1moltam. Ehhez vissza kell \u00e1llnom a f\u00e1jl elej\u00e9re. A RandomAccessFile lehet\u0151s\u00e9get ad arra, hogy a f\u00e1jlban b\u00e1rmilyen helyre pozicion\u00e1ljak, vagyis a mutat\u00f3t oda \u00e1ll\u00edtom be, ahova akarom. Erre szolg\u00e1l a seek() met\u00f3dusa, aminek meg kell adni eg\u00e9sz sz\u00e1mk\u00e9nt a f\u00e1jlmutat\u00f3 hely\u00e9t b\u00e1jtban megadva. Nek\u00fcnk a f\u00e1jl elej\u00e9re van sz\u00fcks\u00e9g\u00fcnk, annak mutat\u00f3ja mindig 0.<\/li>\n<li>17 &#8211; Ha vissza\u00e1lltam az elej\u00e9re, \u00e9s kezdhetem el\u00f6lr\u0151l a beolvas\u00e1st a m\u00e1r megismert m\u00f3don, de most m\u00e1r a db mutat\u00f3k\u00e9nt a t\u00f6mbben l\u00e9v\u0151 k\u00f6vetkez\u0151 \u00fcres helyet mutatja, nem a sorok sz\u00e1m\u00e1t jelenti, hanem azt, hogy hova kell a t\u00f6mbben betenni az \u00e9ppen beolvasott sorban l\u00e9v\u0151 adatot (l\u00e1sd az el\u0151z\u0151 p\u00e9ld\u00e1kat). Zavar\u00f3 lehet, hogy ugyanazt a v\u00e1ltoz\u00f3t egyszer sz\u00e1ml\u00e1l\u00f3nak, m\u00e1skor mutat\u00f3nak haszn\u00e1lom. Ez csak megszok\u00e1s k\u00e9rd\u00e9se. Ha jobban belegondolsz, pontosan ugyanezt tettem meg a <a href=\"https:\/\/www.webotlet.hu\/wp-admin\/post.php?post=451#Kiv\u00e1logat\u00e1s\">kiv\u00e1logat\u00e1sn\u00e1l<\/a> is.<\/li>\n<\/ul>\n<p>N\u00e9zz\u00fck meg ugyanezt ArrayList seg\u00edts\u00e9g\u00e9vel:<\/p>\n<pre class=\"brush: java; gutter: true; highlight: [18]; title: ; notranslate\" title=\"\">\r\nimport java.io.*;\r\nimport java.util.ArrayList;\r\n\r\npublic class Fajlkezelesalapok\r\n{\r\n  public static void main(String&#x5B;] args)\r\n  {\r\n    RandomAccessFile raf;\r\n    String sor;\r\n    ArrayList&lt;String&gt; nevek = new ArrayList&lt;String&gt;();\r\n\r\n    try\r\n    {\r\n      raf = new RandomAccessFile(&quot;nevek.txt&quot;,&quot;r&quot;);\r\n      \r\n      for( sor = raf.readLine(); sor != null; sor = raf.readLine() )\r\n      {\r\n        nevek.add(sor);\r\n      }\r\n      \r\n      raf.close();\r\n    }\r\n    catch( IOException e )\r\n    {\r\n      System.out.println(&quot;HIBA&quot;);\r\n    }\r\n  }\r\n}\r\n<\/pre>\n<p>J\u00f3val egyszer\u0171bb a t\u00f6bbin\u00e9l. Nem kell sz\u00e1molgatni, h\u00e1ny sorb\u00f3l \u00e1ll, akkor sem, ha nem tudjuk mekkora a f\u00e1jl. A lista \u00fagyis akkora lesz, ameddig csak hozz\u00e1adunk valamit. \u00c9s nyilv\u00e1n sem kell tartani, hogy hol a v\u00e9ge, az add() mindig a v\u00e9g\u00e9hez f\u0171zi hozz\u00e1.<\/p>\n<p>A beolvas\u00e1ssal, akkor k\u00e9szen is vagyunk. Eld\u00f6nt\u00f6d majd, melyik szerkezetet haszn\u00e1lod (while, for, do-while). \u00dagy gondolom, a legt\u00f6bb esetben a for ciklus a leghaszn\u00e1lhat\u00f3bb, \u00e9s mivel annak haszn\u00e1lata ismeretlen m\u00e9ret\u0171 f\u00e1jln\u00e1l hasonl\u00edt a kiv\u00e1logat\u00e1sra, \u00edgy ak\u00e1r sablonk\u00e9nt is haszn\u00e1lhat\u00f3. T\u00e1rol\u00e1s \u00e9s beolvas\u00e1s szempontj\u00e1b\u00f3l a lista nagyon hat\u00e9kony, de csak akkor ess neki a haszn\u00e1lat\u00e1nak, ha a t\u00f6mb\u00f6kkel biztosan meg tudod oldani a feladatot.<\/p>\n<h2>\u00daj f\u00e1jl \u00edr\u00e1sa<\/h2>\n<p>Ez sem sokkal bonyolultabb, mint az el\u0151z\u0151ek. Legal\u00e1bbis abban az esetben, ha val\u00f3ban \u00faj f\u00e1jlt kell l\u00e9trehoznunk. Tegy\u00fck fel, van egy neveket tartalmaz\u00f3 t\u00f6mb\u00fcnk, \u00e9s ennek tartalm\u00e1t szeretn\u00e9nk egy f\u00e1jlba ki\u00edrni. A r\u00e9szletes programokat most m\u00e1r nem fogom le\u00edrni, csak a try blokkon bel\u00fcli r\u00e9szekre koncentr\u00e1lok.<\/p>\n<pre class=\"brush: java; gutter: true; highlight: [6,10]; title: ; notranslate\" title=\"\">\r\nRandomAccessFile raf;\r\nString&#x5B;] nevek = { &quot;Bela&quot;,&quot;Geza&quot;,&quot;Eva&quot;,&quot;Adam&quot;,&quot;Orsi&quot; };\r\n\r\ntry\r\n{\r\n  raf = new RandomAccessFile(&quot;nevek2.txt&quot;,&quot;rw&quot;);\r\n\r\n  for( String s: nevek )\r\n  {\r\n    raf.writeBytes(s+&quot;\\n&quot;);\r\n  }\r\n      \r\n  raf.close();\r\n}\r\ncatch( IOException e )\r\n\/\/ ....\r\n\/\/ ....\r\n<\/pre>\n<ul>\n<li>6 &#8211; Az \u00faj f\u00e1jlt &#8220;rw&#8221; vagyis \u00edr\u00e1s m\u00f3dban nyitjuk meg, \u00edgy m\u00f3dos\u00edthat\u00f3 a tartalma. Ha a f\u00e1jl nem l\u00e9tezik, akkor egy \u00faj \u00fcres f\u00e1jl j\u00f6n l\u00e9tre. Ha l\u00e9tezik, akkor megnyitja, \u00e9s az elej\u00e9re poz\u00edcion\u00e1l.<\/li>\n<li>10 &#8211; Sorokat a raf.writeBytes( String ) met\u00f3dussal lehet. Vagyis csak Stringet \u00edrhatunk ki. Azonban felt\u0171nhet az, hogy a Stringhez hozz\u00e1f\u0171z\u00f6k egy &#8220;\\n&#8221; r\u00e9szt is. Ez a sordob\u00e1s karaktere. Vagyis minden esetben neked kell \u00faj sort kezdeni! A ki\u00edrat\u00e1s nem sz\u00fcks\u00e9ges, hogy sz\u00e1ml\u00e1l\u00f3val rendelkez\u0151 ciklussal t\u00f6rt\u00e9njen, hiszen a neveket tartalmaz\u00f3 t\u00f6mb minden elem\u00e9t ki akarjuk \u00edrni, ez\u00e9rt egy for each ciklussal ezt gond n\u00e9lk\u00fcl megtehetj\u00fck.<\/li>\n<\/ul>\n<p>A sorokat tetsz\u0151leges dolgokat tartalmazhatnak, a l\u00e9nyeg, hogy minden sor v\u00e9g\u00e9n legyen ott a sort\u00f6r\u00e9s karaktere. A gond akkor van, ha bele szeretn\u00e9l n\u00e9zni a f\u00e1jlba, \u00e9s mondjuk jegyzett\u00f6mbbel megnyitod. Azt l\u00e1thatod, hogy a neveket egym\u00e1s mell\u00e9 \u00edrta egy sorba. Semmi gond, itt csak arr\u00f3l van sz\u00f3, hogy a jegyzett\u00f6mb buta, \u00e9s a raf.writeBytes() \u00e1ltal haszn\u00e1lt sordob\u00e1s karaktereket nem ismeri fel rendesen, ugyanis Linux \u00e9s Windows k\u00f6rnyezetben m\u00e1s vez\u00e9rl\u0151 karakterek jelentik a sorv\u00e9geket. Nyisd meg Geany vagy NetBeans szerkeszt\u0151vel \u00e9s l\u00e1tni fogod, hogy minden rendben van.<\/p>\n<h2>Megl\u00e9v\u0151 f\u00e1jl v\u00e9g\u00e9hez hozz\u00e1f\u0171z\u00e9s<\/h2>\n<p>Megl\u00e9v\u0151 f\u00e1jlok kezel\u00e9sekor a f\u00e1jl v\u00e9g\u00e9hez \u00edr\u00e1skor van a legk\u00f6nnyebb dolgunk. Ha megnyitottuk a f\u00e1jlt, egyszer\u0171en a v\u00e9g\u00e9re kell ugranunk, \u00e9s raf.writeBytes()-szal \u00edrni \u00e9sz n\u00e9lk\u00fcl, amit csak akarunk. Na de hogy ugrunk a v\u00e9g\u00e9re? A RandomAccessFile rendelkezik egy seek() nev\u0171 met\u00f3dussal, mellyel a f\u00e1jlban tetsz\u0151leges helyre pozicion\u00e1lhatunk. M\u00e1r haszn\u00e1ltuk is, a raf.seek(0) a f\u00e1jl elej\u00e9re pozicion\u00e1lta a f\u00e1jlmutat\u00f3t. Mivel a f\u00e1jlban sz\u00f6veges tartalom van, minden egyes karakter egy b\u00e1jtot jelent. Akkor tudnunk kellene, hogy mennyi cucc van a f\u00e1jlban, \u00e9s megmondjuk, hogy ezek ut\u00e1n \u00e1llunk. L\u00e1ssuk akkor hogyan is tegy\u00fck ezt meg:<\/p>\n<pre class=\"brush: java; gutter: true; highlight: [7]; title: ; notranslate\" title=\"\">\r\nRandomAccessFile raf;\r\n\r\ntry\r\n{\r\n  raf = new RandomAccessFile(&quot;nevek.txt&quot;,&quot;rw&quot;);\r\n\r\n  raf.seek( raf.length() );\r\n\/\/ innent\u0151l j\u00f6het az \u00edr\u00e1s, m\u00e1r a f\u00e1jl v\u00e9g\u00e9n vagyunk\r\n\r\n  raf.close();\r\n}\r\ncatch( IOException e )\r\n\/\/ ....\r\n<\/pre>\n<p>Nem sok mindent kell itt megmagyar\u00e1zni. A raf.seek() a f\u00e1jl adott b\u00e1jtja (karaktere) el\u00e9 pozicion\u00e1lja a f\u00e1jlmutat\u00f3t, \u00e9s onnant\u00f3l \u00edrhatunk. A raf.length() pedig megadja, hogy egy adott f\u00e1jl h\u00e1ny b\u00e1jtb\u00f3l \u00e1ll, \u00edgy azonnal a v\u00e9g\u00e9re ugrunk.<\/p>\n<h2>Adott sor kicser\u00e9l\u00e9se<\/h2>\n<p>Na, kezd\u0151dik&#8230; \u00c9rdekes feladat az, amikor egy adott sort kell kicser\u00e9lni az \u00e1llom\u00e1nyban. A sz\u00f6veges f\u00e1jlt nem \u00fagy kell elk\u00e9pzelni, mint egy k\u00fcl\u00f6n\u00e1ll\u00f3 sorokb\u00f3l \u00e1ll\u00f3 valamit, aminek mi l\u00e1tjuk. Ez egy karakterfolyam, melyben n\u00e9ha &#8220;sorv\u00e9g&#8221; karakterek \\n-ek tal\u00e1lhat\u00f3ak. \u00cdgy val\u00f3j\u00e1ban nagyon neh\u00e9z megoldani azt, hogy egy adott sort cser\u00e9lj\u00fcnk ki, hiszen a sorok nem egyforma m\u00e9ret\u0171ek.<\/p>\n<p>A f\u00e1jl teh\u00e1t nem \u00edgy n\u00e9z ki:<\/p>\n<p>Bela<br \/>\nJozsef<br \/>\nAnna<\/p>\n<p>Hanem \u00edgy:<\/p>\n<p>Bela\\nJozsef\\nAnna<\/p>\n<p>Na most ide Jozsef helyere besz\u00farni egy Adam-ot meglehet\u0151sen \u00e9rdekes eredm\u00e9nyeket ad. M\u00e9g a \\n is bezavar, hiszen az is ugyanolyan karakter (b\u00e1jt), mint az \u00f6sszes bet\u0171. M\u00e9g ha pontosan pozicion\u00e1lsz a m\u00e1sodik n\u00e9v elej\u00e9re a seek(6)-tal, akkor is rossz az eredm\u00e9ny, hiszen ezt kapod:<\/p>\n<p>Bela<br \/>\nAdam<br \/>\nf<br \/>\nAnna<\/p>\n<p>Itt nincs mese, k\u00f6zvetlen\u00fcl nincs csere. Be kell olvasni egy String t\u00f6mbbe a f\u00e1jl tartalm\u00e1t, kicser\u00e9lni Jozsef-et Adam-ra, vissza\u00e1llsz a f\u00e1jl elej\u00e9re \u00e9s az eg\u00e9szet ki\u00edrod \u00fajra. Ok\u00e9, \u00e9s ha a csere ut\u00e1n a f\u00e1jl hosszabb lett? Semmi gond, a f\u00e1jlnak megn\u0151 a m\u00e9rete is. \u00c9s mi van, ha a csere ut\u00e1n r\u00f6videbb lett? Gond. Mert a r\u00e9gi f\u00e1jlb\u00f3l ottmaradt a marad\u00e9k a v\u00e9g\u00e9n. De mindj\u00e1rt megl\u00e1tod, ez nem akkora gond. L\u00e1ssuk akkor a teljes feladatot, ami minden esetben kicser\u00e9l egy adott sort egy sz\u00f6veges f\u00e1jlban. Az egyszer\u0171s\u00e9g kedv\u00e9\u00e9rt tudjuk, hogy 3 nev\u00fcnk van a f\u00e1jlban. A m\u00e1sodikat akarjuk kicser\u00e9lni egy \u00fajra.<\/p>\n<pre class=\"brush: java; gutter: true; highlight: [9,10,11,12,13,16,17,19,20,21,22,24,26]; title: ; notranslate\" title=\"\">\r\nRandomAccessFile raf;\r\nString sor;\r\nString&#x5B;] nevek = new String&#x5B;3]; \r\n\r\ntry\r\n{\r\n  raf = new RandomAccessFile(&quot;nevek.txt&quot;, &quot;rw&quot;);\r\n\r\n  int i = 0;\r\n  for (sor = raf.readLine(); sor != null; sor = raf.readLine())\r\n  {\r\n    nevek&#x5B;i] = sor;\r\n    i++;\r\n  }\r\n      \r\n  nevek&#x5B;1] = &quot;Pal&quot;;\r\n  raf.seek(0);\r\n\r\n  for (String s : nevek)\r\n  {\r\n    raf.writeBytes(s+&quot;\\n&quot;);\r\n  }\r\n\r\n  if( raf.length() &gt; raf.getFilePointer() )\r\n  {\r\n    raf.setLength( raf.getFilePointer() );\r\n  }\r\n\r\n  raf.close();\r\n}\r\ncatch( IOException e )\r\n\/\/ ....\r\n\/\/ ....\r\n<\/pre>\n<p>Akkor apr\u00e1nk\u00e9nt, de szerintem ha m\u00e1r id\u00e1ig eljutott\u00e1l a nagy r\u00e9sze teljesen \u00e9rthet\u0151. Amivel m\u00e1r tal\u00e1lkozt\u00e1l, csak c\u00edmszavakban fejtem ki.<\/p>\n<ol>\n<li>9-13 &#8211; A f\u00e1jl tartalm\u00e1nak beolvas\u00e1sa.<\/li>\n<li>16 &#8211; Kicser\u00e9lj\u00fck a t\u00f6mbben a 2. nevet.<\/li>\n<li>17 &#8211; Vissza\u00e1llunk a f\u00e1jl elej\u00e9re.<\/li>\n<li>19-22 &#8211; Ki\u00edrjuk a t\u00f6mbb\u0151l a neveket a f\u00e1jlba.<\/li>\n<li>24 &#8211; Megn\u00e9zz\u00fck, hogy a f\u00e1jl hosszabb-e, mint az a poz\u00edci\u00f3, ahol most \u00e1llunk (vagyis a t\u00f6mb ki\u00edr\u00e1s\u00e1nak befejez\u00e9se ut\u00e1n).<\/li>\n<li>26 &#8211; Ha hosszabb, akkor a f\u00e1jl m\u00e9ret\u00e9t be\u00e1ll\u00edtjuk arra a poz\u00edci\u00f3ra \u00e9s ez lesz az \u00faj f\u00e1jl v\u00e9ge, mert az el\u0151z\u0151 n\u00e9vsor marad\u00e9ka m\u00e9g ott van a v\u00e9g\u00e9n!<\/li>\n<\/ol>\n<p>Tal\u00e1n m\u00e9g egyszer\u0171bb az a megold\u00e1s, hogy a f\u00e1jl beolvas\u00e1sa ut\u00e1n azonnal null\u00e1zzuk a m\u00e9ret\u00e9t, \u00e9s csak ki\u00edrjuk a String t\u00f6mb tartalm\u00e1t \u00e9sz n\u00e9lk\u00fcl. Akkor m\u00e9g a seek()-et is megsp\u00f3rolhatjuk, mivel a f\u00e1jl m\u00e9rete 0, vagyis csak az elej\u00e9n lehet\u00fcnk.<\/p>\n<pre class=\"brush: java; gutter: true; highlight: [15]; title: ; notranslate\" title=\"\">\r\nRandomAccessFile raf;\r\nString sor;\r\nString&#x5B;] nevek = new String&#x5B;3]; \r\n\r\ntry\r\n{\r\n  raf = new RandomAccessFile(&quot;nevek.txt&quot;, &quot;rw&quot;);\r\n\r\n  int i = 0;\r\n  for (sor = raf.readLine(); sor != null; sor = raf.readLine())\r\n  {\r\n    nevek&#x5B;i] = sor;\r\n    i++\r\n  }\r\n  raf.setLength(0); \/\/ f\u00e1jl tartalm\u00e1nak t\u00f6rl\u00e9se\r\n\r\n  nevek&#x5B;1] = &quot;Pal&quot;;\r\n\/\/ j\u00f6het a ki\u00edr\u00e1s, stb\r\n<\/pre>\n<h2>Sor besz\u00far\u00e1sa f\u00e1jlba (nem a v\u00e9g\u00e9re)<\/h2>\n<p>Na ez m\u00e1r t\u00e9nyleg \u00e9rdekes. Egy kis \u00f6tlettel ez is megoldhat\u00f3. Nyilv\u00e1n itt sem lehet \u00e9sz n\u00e9lk\u00fcl \u00edrni sehova sem. B\u00e1rhova \u00edrsz a f\u00e1jlba, ha nem a v\u00e9g\u00e9hez f\u0171z\u00f6d hozz\u00e1, akkor mindenk\u00e9ppen fel\u00fcl\u00edrsz valamit. Adja mag\u00e1t a dolog, hogy itt is t\u00f6mbbe t\u00e1rold el a f\u00e1jl tartalm\u00e1t. Igen \u00e1m, de a t\u00f6mbbe besz\u00farni nem lehet. Egyr\u00e9szt mert akkor megn\u0151ne a m\u00e9rete (t\u00f6mb m\u00e9rete fix!), m\u00e1sr\u00e9szt a besz\u00far\u00e1s poz\u00edci\u00f3j\u00e1t\u00f3l kezd\u0151d\u0151en mindenkit od\u00e9bb kell pakolni eggyel h\u00e1tr\u00e1bb (egyes\u00e9vel?). Van egy nem t\u00fal v\u00e9szes megold\u00e1s.<\/p>\n<p>Tegy\u00fck fel, hogy a 4 soros f\u00e1jlunk k\u00f6zep\u00e9re szeretn\u00e9nk egy \u00faj nevet besz\u00farni.<\/p>\n<p>Hasonl\u00f3an az el\u0151z\u0151h\u00f6z, el\u0151bb beolvasom a f\u00e1jl tartalm\u00e1t. Igen \u00e1m, de 4 elem\u0171 t\u00f6mbben fogom t\u00e1rolni a neveket, hogy rakom be k\u00f6z\u00e9j\u00fck az 5.-et? Sehogy. El\u0151sz\u00f6r ki\u00edrom az el\u0151tte l\u00e9v\u0151ket, majd az \u00faj nevet, v\u00e9g\u00fcl az ut\u00e1na k\u00f6vetkez\u0151ket. A t\u00f6mbbe nem rakom bele. Annyit kell csak tudnom, melyik ut\u00e1n akarom besz\u00farni, mert ott kell meg\u00e1llnom a nevek ki\u00edr\u00e1sakor egy pillanatra, ut\u00e1na meg onnan folytathatom.<\/p>\n<pre class=\"brush: java; gutter: true; highlight: [16,18,19,20,21,23,25,26,27,28]; title: ; notranslate\" title=\"\">\r\nRandomAccessFile raf;\r\nString sor;\r\nString&#x5B;] nevek = new String&#x5B;4];\r\n\r\ntry\r\n{\r\n  raf = new RandomAccessFile(&quot;nevek.txt&quot;, &quot;rw&quot;);\r\n  nevek = new String&#x5B;4];\r\n\r\n  int i = 0;\r\n  for ( sor = raf.readLine(); sor != null; sor = raf.readLine() )\r\n  {\r\n    nevek&#x5B;i++] = sor;\r\n  }\r\n\r\n  raf.setLength(0);\r\n      \r\n  for( int j = 0; j &lt; 2; j++ )\r\n  {\r\n    raf.writeBytes(nevek&#x5B;j]+&quot;\\n&quot;);\r\n  }\r\n      \r\n  raf.writeBytes(&quot;Teodor\\n&quot;);\r\n\r\n  for( int j = 2; j &lt; nevek.length; j++ )\r\n  {\r\n    raf.writeBytes(nevek&#x5B;j]+&quot;\\n&quot;);\r\n  }\r\n\r\n  raf.close();\r\n}\r\ncatch ( IOException e )\r\n\/\/ stb...\r\n<\/pre>\n<ul>\n<li>16 &#8211; F\u00e1jl tartalm\u00e1nak t\u00f6rl\u00e9se<\/li>\n<li>18-21 &#8211; Besz\u00far\u00e1s el\u0151tti r\u00e9szek ki\u00edr\u00e1sa.<\/li>\n<li>23 &#8211; \u00daj sor besz\u00far\u00e1sa a f\u00e1jlba<\/li>\n<li>25-28 &#8211; Besz\u00far\u00e1s ut\u00e1ni r\u00e9szek ki\u00edr\u00e1sa.<\/li>\n<\/ul>\n<p>Hogy ez mennyivel egyszer\u0171bb list\u00e1val&#8230;<\/p>\n<pre class=\"brush: java; gutter: true; highlight: [14,16,17,18,19,20]; title: ; notranslate\" title=\"\">\r\nRandomAccessFile raf;\r\nString sor;\r\nArrayList&lt;String&gt; nevek = new ArrayList&lt;String&gt;();\r\n\r\ntry\r\n{\r\n  raf = new RandomAccessFile(&quot;nevek.txt&quot;,&quot;rw&quot;);\r\n   \r\n  for( sor = raf.readLine(); sor != null; sor = raf.readLine() )\r\n  {\r\n    nevek.add(sor);\r\n  }\r\n \r\n  nevek.add(2, &quot;Teodor&quot;);\r\n \r\n  raf.setLength(0);\r\n  for ( String s : nevek)\r\n  {\r\n    raf.writeBytes(s+&quot;\\n&quot;);\r\n  }\r\n\r\n  raf.close();\r\n}\r\ncatch ( IOException e )\r\n\r\n<\/pre>\n<ul>\n<li>14 &#8211; A beolvasott list\u00e1ba a megfelel\u0151 helyre besz\u00farok egy elemet, ami automatikusan h\u00e1tr\u00e1bb tolja a m\u00f6g\u00f6tte l\u00e9v\u0151ket a list\u00e1ban.<\/li>\n<li>16 &#8211; F\u00e1jl tartalm\u00e1nak t\u00f6rl\u00e9se<\/li>\n<li>17-20 &#8211; V\u00e1logat\u00e1s n\u00e9lk\u00fcl ki\u00edrom az eg\u00e9sz list\u00e1t a f\u00e1jlba.<\/li>\n<\/ul>\n<p>Ezek voltak a f\u00e1jlkezel\u00e9s alapjai, amikor egy sorban egyetlen sz\u00f6veges adat szerepelt. A k\u00e9s\u0151bbiek sem sokkal bonyolultabbak. Ha sz\u00e1mokkal dolgozn\u00e1nk, akkor a beolvasott sorokat azonnal sz\u00e1mm\u00e1 kellene alak\u00edtani az Integer.parseInt() met\u00f3dussal, \u00e9s k\u00e9sz.<\/p>\n<p>A gond akkor lesz, ha egy sor t\u00f6bb \u00f6sszetartoz\u00f3 adatot tartalmaz. Mondjunk egy kutya menhely lak\u00f3inak adatait, \u00e9s ezeket az adatokat valamivel elv\u00e1lasztjuk egym\u00e1st\u00f3l a soron bel\u00fcl. Erre egy p\u00e9ldaobjektumot m\u00e1r l\u00e1thatt\u00e1l kuty\u00e1ra az <a title=\"Java programoz\u00e1s 13. \u2013 Oszt\u00e1lyok \u00e9s objektumok\" href=\"http:\/\/www.webotlet.hu\/?p=675\">Oszt\u00e1lyok \u00e9s objektumok<\/a> t\u00e9mak\u00f6rben. A <a title=\"Java programoz\u00e1s 15. \u2013 String\" href=\"http:\/\/www.webotlet.hu\/?p=619\">String<\/a> met\u00f3dusokat is k\u00edv\u00fclr\u0151l kell f\u00fajnod ahhoz, hogy f\u00e1jlkezel\u00e9s ter\u00fclet\u00e9n tov\u00e1bb haladhassunk.<\/p>\n<p>A f\u00e1jlkezel\u00e9s alapeseteit (beolvas\u00e1s, ki\u00edr\u00e1s, hozz\u00e1f\u0171z\u00e9s, csere, besz\u00far\u00e1s) m\u00e1r megismerhetted, \u00e9s ha ezeket alkalmazni is tudod, akkor j\u00f6het a m\u00e9lyebb v\u00edz egy m\u00e1sik leck\u00e9ben.<\/p>\n<p>Na, megvan a 3 fajta ciklusb\u00f3l melyiket nem szeretem a beolvas\u00e1skor? Ok\u00e9, sokat nem seg\u00edtettem, mert mindenhol for-t haszn\u00e1ltam. Maradt 50%. Pr\u00f3b\u00e1lj a 3 ciklusfajt\u00e1val beolvastatni egy \u00fcres f\u00e1jlt. Melyiknek lesz gondja vele?<\/p>\n<p>(A tematika szerint a saj\u00e1t met\u00f3dusok lesz a k\u00f6vetkez\u0151 lecke, ez m\u00e9g nincs k\u00e9sz, addig \u00e1tugorjuk)<\/p>\n<h4>K\u00f6vetkez\u0151 lecke: <a title=\"Java programoz\u00e1s 23. \u2013 Saj\u00e1t objektumok\" href=\"http:\/\/www.webotlet.hu\/?p=40\">Saj\u00e1t objektumok<\/a><\/h4>\n","protected":false},"excerpt":{"rendered":"<p>F\u00e1jlkezel\u00e9s, avagy dolgozzunk is m\u00e1r valamit A k\u00f6z\u00e9piskolai programoz\u00e1s sor\u00e1n szinte minden esetben parancssoros fel\u00fcleten kereszt\u00fcl dolgozunk, ott tekintj\u00fck meg a kimeneteket, \u00e9s az esetleges interakci\u00f3kat (g\u00e9peld be a neved, adj meg egy sz\u00e1mot, stb) \u00e9s azon kereszt\u00fcl bonyol\u00edtjuk. Tanulm\u00e1nyaink <a class=\"more-link\" href=\"https:\/\/www.webotlet.hu\/?p=627\">Tov\u00e1bb <span class=\"screen-reader-text\">  Java programoz\u00e1s 21. &#8211; F\u00e1jlkezel\u00e9s alapjai<\/span><span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[100],"tags":[23,208,22,24,86,144,16,25,206,207,26,15,209],"class_list":["post-627","post","type-post","status-publish","format-standard","hentry","category-java-halado-leckek","tag-beszuras","tag-catch","tag-fajlkezeles","tag-hozzafuzes","tag-java","tag-java_programozas","tag-lista","tag-randomaccessfile","tag-readline","tag-seek","tag-szovegfajl","tag-tomb","tag-try"],"_links":{"self":[{"href":"https:\/\/www.webotlet.hu\/index.php?rest_route=\/wp\/v2\/posts\/627","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.webotlet.hu\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.webotlet.hu\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.webotlet.hu\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.webotlet.hu\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=627"}],"version-history":[{"count":71,"href":"https:\/\/www.webotlet.hu\/index.php?rest_route=\/wp\/v2\/posts\/627\/revisions"}],"predecessor-version":[{"id":2392,"href":"https:\/\/www.webotlet.hu\/index.php?rest_route=\/wp\/v2\/posts\/627\/revisions\/2392"}],"wp:attachment":[{"href":"https:\/\/www.webotlet.hu\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=627"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.webotlet.hu\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=627"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.webotlet.hu\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=627"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}