Në këtë artikull, unë dua të diskutoj në detaje se si të punoj me skedarë duke përdorur Java.

  1. Skedari
  2. Leximi dhe shkrimi i përmbajtjes

Skedari

Epo, le të fillojmë së pari me të kuptuarit se çfarë është skedari dhe sistemi i skedarëve.

Sistemi i skedarëve

Le të imagjinojmë kujtesën tonë të makinës si një kanavacë e madhe qelizash që është në gjendje të ruajë disa të dhëna. Gjithçka që kemi në makinën tonë ruhet atje. Për ta mbajtur atë të organizuar, ne kemi një sistem skedarësh. Sistemi i skedarëve kontrollon se si ruhen të dhënat. Pa të, të dhënat do të ishin një trup i madh i të dhënave pa asnjë mënyrë për të treguar se ku ndalon një pjesë e të dhënave dhe fillon tjetra. Pra, duke i ndarë të dhënat dhe duke u dhënë atyre një emër (skedar të vetëm) na ndihmon të gjejmë dhe punojmë shpejt me të dhënat. Sistemi i skedarëve përbëhet nga skedarë dhe direktori (dosje). Ato janë të organizuara në një strukturë peme. Ekziston një direktori rrënjë nga ku fillon e gjithë struktura. Çdo skedar dhe direktori ka një shteg skedari unik, me anë të kësaj rruge ne mund t'i gjejmë dhe të punojmë me to.

Skedari

Skedari është të dhëna të izoluara me një emër dhe një rrugë unike të skedarit në sistemin e skedarëve. Skedari ka një kokë dhe përmbajtje. Brenda kokës, ai do të ketë meta të dhëna - të dhëna për këtë skedar si madhësia, lloji, mënyra e leximit, lejet, modifikimi i fundit, etj. Pjesa e përmbajtjes do të ketë në fakt përmbajtjen e atij skedari.

Në Java, skedarët dhe drejtoritë përfaqësohen me një objekt File

Pothuajse çdo gjuhë programimi mund të manipulojë (lexojë, shkruajë, krijojë, fshijë) skedarët dhe drejtoritë duke përdorur kornizat dhe klasat e gatshme të integruara. Sidoqoftë, është e rëndësishme të mbani në mend se skedarët janë vetëm një grumbull të dhënash në memorie dhe ato janë strukturuar praktikisht si një sistem skedari.

java.io.Klasa e skedarit

Paketa java.io (io — hyrje/dalje) do të ketë shumicën e klasave që do të duhet të dimë për të punuar me skedarë në java. Klasa e parë që do t'i hedhim një vështrim është klasa File. Ai përfaqëson skedarët dhe drejtoritë në Java. Gjatë krijimit të tij, ne duhet të kalojmë shtegun e skedarit (në thelb duhet të tregojmë se cilin skedar ose drejtori duhet të përfaqësojë si një objekt java). Ne nuk mund të lexojmë ose shkruajmë të dhëna në këtë skedar duke përdorur vetëm objektin File.

Kryesisht, ne mund ta përdorim këtë objekt për të:

  1. Merrni meta të dhëna (të dhëna rreth të dhënave) në lidhje me skedarin tonë. Për shembull, madhësia, modifikimi i fundit dhe të dhëna të tjera të dobishme.
  2. Ne mund ta krijojmë këtë skedar/direktori nëse nuk ekziston (ose ta anashkalojmë nëse ekziston)
  3. Mund ta fshijmë.

Le të shohim kodin java. Supozoni, unë kam një skedar test.txt në desktopin tim me përmbajtje Hello, World!.

  • Klasa e skedarëve përfaqëson skedarët dhe drejtoritë.
  • Për të krijuar një objekt File, ne duhet të kalojmë rrugën e skedarit për një skedar që duam të përfaqësojmë si një objekt java.
  • Ka shumë metoda të dobishme për të mbledhur informacione rreth skedarëve/drejtorive.

Ekzistojnë dy lloje të shtigjeve të skedarëve:
1. Shtegu absolut që fillon nga rrënja e sistemit të skedarëve.
Për shembull, /Users/beknazarsuranchiyev/Desktop/test.txt

/ është root për Mac dhe për Windows mund të jetë drejtuesi C

2. Rruga relative që 'përpilohet' nga vendi ku po ekzekutohet kodi.
Për shembull, src/test/myFile.txt

— — — — — — — — — — — — — — — — — — — — — — — — —
Ndonjëherë do të shihni kufijtës \\ dhe / në shtegun e skedarit.

\ — është për sistemin operativ Windows. Meqenëse \ është një karakter i veçantë në Java, ne duhet t'i shpëtojmë atij me një tjetër \ në mënyrë që të kemi \\

/ — është për sistemin operativ të bazuar në Linux (edhe Mac e përdor atë).
Unë rekomandoj të përdorni gjithmonë delimeter / të bazuar në linx (do të funksionojë nëse përdorni kodin edhe në makinat wndows).

Nëse një skedar ose drejtori nuk ekziston në shtegun e specifikuar, ne mund t'i krijojmë ato.

  • ne mund të krijojmë një skedar bosh duke përdorur metodën createNewFile().
  • ai hedh një "përjashtim" të pakontrolluar, kështu që ne duhet ta trajtojmë atë duke deklaruar ose kapur (në këtë shembull thjesht duke deklaruar).
  • Në këtë shembull, ne po krijojmë skedarin tonë këtu: /Users/beknazarsuranchiyev/Desktop/apple.txt
    nëse drejtoriaDesktop nuk do të ekzistonte, kodi do të nuk arrin të krijojë skedarin tonëapple.txt. Pra, createNewFile() nuk është në gjendje të krijojë drejtori të nënvizuara nëse ato nuk ekzistojnë. Ne do të duhet t'i krijojmë ato veçmas.

Le të krijojmë drejtori

  • mkdir() është një metodë për të krijuar një drejtori (duke marrë emrin nga Linux)
  • nëse një drejtori nuk krijohet, ai nuk do të bëjë përjashtim, por do të kthejë false (një arsye pse dosja nuk mund të krijohet është lejet)
  • Ekziston mkdirs() që mund të krijojë drejtori joekzistuese prindërore.

Mund të fshijmë skedarët dhe dosjet duke përdorur komandën delete().

Unë dua të diskutoj më shumë për lejet

  • Mund ta zbulojmë qasjen në lexim me metodën carRead().
  • Mund të zbulojmë aksesin e shkrimit me metodën canWrite().
  • Mund ta zbulojmë aksesin e ekzekutimit me metodën canExecute().

Ok, disa informacione më të dobishme:

  1. Zbuloni se cili ID po ekzekuton kodin: System.out.println(System.getProperty("user.name"));
  2. Nëse keni nevojë për më shumë informacion në lidhje me lejet e skedarëve/drejtorive, mund të provoni të ekzekutoni Linux komandat nga kodi Java. Ky është opsioni i fundit për të shkuar.

Leximi dhe shkrimi i përmbajtjes

Në përgjithësi, ekzistojnë dy mënyra për të punuar me leximin dhe shkrimin e skedarëve në Java.

  1. InputStream dhe OutputStream.
    Klasat Stream përdoren për futjen dhe daljen e të gjitha llojeve të të dhënave binare ose bajt.
  2. Reader dhe Writer.
    Klasat Reader dhe Writer përdoren për futjen dhe nxjerrjen e karaktereve dhe vargjeve. Në thelb, skedarët e tekstit.

Le të flasim për Streams

Të dy InputStream/OutoutStream dhe Reader/Writer përdorin transmetime në sfond (Edhe Reader/Writer nuk ka një transmetim në emrin e tyre). Ideja kryesore e transmetimit është të lexosh/shkruash pjesë-pjesë. Për shembull, ne duam të lexojmë përmbajtjen e një skedari teksti të madh (100 GB le të themi) dhe le të themi të numërojmë numrin e shkronjave. Leximi dhe ngarkimi i të gjithë përmbajtjes në memorie (memoria RAM) nuk do të ishte alternativa më e mirë, kujtesa thjesht mund të tejmbushet. Megjithatë, leximi i të dhënave pjesë-pjesë nuk do të tejmbush memorien, sigurisht nëse nuk ruajmë gjithçka në memorie gjithashtu.

Le të shohim se si mund të lexojmë përmbajtjen e skedarit duke përdorur InputStream

  • Do të printojë Hello, World! nëse skedari im nën /Users/beknazarsuranchiyev/Desktop/test.txt do të ketë përmbajtje Hello, World!.
  • while((b = in.read()) != -1) {content.append((char)b);} kjo është pjesa më e rëndësishme e kodit. in.read() do të lexojë pjesën e përmbajtjes dhe do ta kthejë atë si int. Kur të përdoret herën tjetër, do të lexojë pjesën tjetër e kështu me radhë. Kur do të kthehet -1 do të thotë se ka arritur në fund të përmbajtjes së skedarit. Së pari, ne po i caktojmë vlerën e metodës in.read() variablit tonë b, më pas po kontrollojmë nëse është -1 apo ​​jo. Nëse është -1, ne po dalim nga cikli dhe nëse nuk është, ne po i vendosim vlerë SpringBuilder-it tonë.
  • Ne gjithmonë duhet të mbyllim burimet tona (skedarët, lidhjet e bazës së të dhënave). Në këtë rast, ne po e mbyllim atë në bllokun finally sepse ai funksionon gjithmonë (nuk ka rëndësi nëse ndodh një përjashtim apo jo). in.close() hedh gjithashtu përjashtimin e kontrolluar, kështu që ne po e trajtojmë atë edhe atje.
  • Në këtë shembull, ne po lexojmë çdo bajt veç e veç, por ekziston një mundësi për të lexuar shumë bajt në të njëjtën kohë. Leximi i shumë bajteve në të njëjtën kohë të skedarëve të tekstit kërkon një kod shtesë për të kthyer bajt në paraqitjen e vargut (më mirë të përdorni klasa lexues/shkrimtar).
  • Kodi i mësipërm është një version pak i vjetër i përdorimit të përjashtimeve dhe mbylljes. Ne do të shohim një mënyrë më të mirë për ta bërë atë.

Le të shohim një shembull tjetër:

Ky është kodi që bën shumë më tepër, por duket më i shkurtër dhe më i bukur. Ai do të bëjë një kopje të sourceFile në vendin me një emër të specifikuar në targetFile.

  • try() {} provoni me burime. Ideja kryesore është që në fund do t'i mbyllë burimet automatikisht, kështu që ne nuk duhet të përdorim bllokun finally dhe t'i mbyllim ato manualisht. Mund ta shihni, ne hapëm dy burime atje dhe nuk duhet të shqetësohemi për mbylljen e tyre. Përpjekja me burime do ta trajtojë atë. Nëse dëshironi të krijoni klasën tuaj të personalizuar që do të funksionojë me të, do t'ju duhet të implementoni ndërfaqen Closeable.
  • byte[] buffer = new byte[1024]; po e kalojmë në metodën read(). Ne po specifikojmë numrin e bajteve për t'u lexuar si një pjesë. Do të përmirësojë efikasitetin e leximit dhe shkrimit të përgjithshëm.
  • Gjëja e fundit që duhet theksuar është mënyra se si shkruajmë në skedar. new FileOutputStream(targetFile) është përgjegjës për të shkruar përmbajtjen në skedar (nëse skedari nuk ekziston, ai do të krijojë një të tillë). out.write(buffer, 0, b); përdoret për të shkruar përmbajtje në skedar.
  • 'Inputs' është për lexim dhe 'Outputs' është për shkrim.

Tani, le të flasim për Lexuesit dhe Shkrimtarët

Ata gjithashtu përdorin transmetime, ndryshimi i vetëm është se ato janë krijuar posaçërisht për të punuar me skedarë teksti (karaktere, vargje).

  • Siç mund ta shihni, ai ka një koncept të ngjashëm me Streams.

Buferët (klasat e nivelit të lartë)

Klasat e tamponit ekzistojnë edhe për Streams dhe Reader/Writers. Ato janë klasa mbështjellëse që ofrojnë metoda më abstrakte për të punuar me skedarë në një mënyrë më të lehtë. Ekzistojnë dy lloje të klasave IO që në fakt mund të lexojnë dhe shkruajnë.

Niveli i lartë dhe i ulët. Deri më tani kemi punuar vetëm me klasa të nivelit të ulët. Siç kemi thënë tashmë, klasat e nivelit të lartë ofrojnë metoda shtesë për të punuar me të dhënat e skedarëve në një nivel më të lartë, për shembull për të lexuar rreshtat e tëra.

  • Mund të shihni se new BufferedReader(new FileReader(file)) po mbyll lexuesin e nivelit të ulët. Kjo është mënyra se si ne përdorim klasat IO të nivelit të lartë duke mbështjellë klasat IO të nivelit të ulët.
  • në këtë shembull, ne kemi një metodë që do të lexojë përmbajtjen e skedarit të tekstit dhe do ta kthejë atë si String.
  • Vini re, ne kemi përdorur stream (jo IO streams) të java këtu për ta bërë kodin më të shkurtër.

E njëjta ide e klasave buffer kemi edhe klasat "Stream". Rekomandohet gjithmonë përdorimi i klasave të nivelit të lartë të tamponit.

Përmbledhje

Ne përdorim klasën File për të përfaqësuar skedarët dhe drejtoritë në java. Mund të marrim informacione për këtë skedar. Mund të krijojmë skedarë/drejtori të reja ose mund t'i fshijmë. Megjithatë, ne nuk mund ta përdorim atë për të lexuar ose shkruar përmbajtje.

Për të lexuar dhe shkruar skedarë Java përdor Streams. Ideja kryesore është të lexoni/shkruani përmbajtjen e skedarit pjesë-pjesë.

Ekzistojnë dy lloje klasash IO për të lexuar dhe shkruar përmbajtjen e klasës.

  1. Rrjedhat hyrëse/dalëse. Ata lexojnë dhe shkruajnë të gjitha llojet e të dhënave. Punon në nivel binar.
  2. Lexuesit/Shkrimtarët. Ata punojnë për skedarët e përmbajtjes së tekstit.

Buffer ose i nivelit të lartë janë klasa që janë klasa mbështjellëse të klasave IO të nivelit të ulët. Klasat buffer do të provojnë metoda shtesë për të punuar me përmbajtjen e skedarit në një nivel më të lartë. Është gjithmonë praktikë e mirë të përdorni klasa të buferuara, përveç nëse jeni duke bërë diçka specifike dhe keni nevojë për qasje të nivelit të ulët në përmbajtje.

Kjo është e gjitha për sot, kalofshi mirë!