|
System.in ir System.out |
InputStream ir OutputStream |
Klasė File |
Reader ir Writer |
Foto peržiūra |
Užduotis |
System.out.println(eilutė);Tačiau norėdami net ir labai paprastus duomenis įvesti iš klaviatūros programos pradžioje rašydavome gana mįslingas eilutes:
BufferedReader br = new BufferedReader ( new InputStreamReader (System.in));Kur gi čia šuo pakastas? Kodėl ir iš klaviatūros duomenų negalėtume įvedinėti naudodamiesi, pavyzdžiui, tokiomis komandomis:
System.in.read();Galėtume. Iš tiesų rašant Java programas galime naudotis ne tik paprastu sisteminiu duomenų išvedimo į ekraną srautu System.out bet ir analogišku duomenų įvedimo iš klaviatūros srautu System.in. Pasižiūrėkime, pavyzdžiui, kaip šie srautai ,,veikia" tokioje visai paprastoje programoje:
public class SystIvIsv { public static void main (String [] args) throws Exception {int iv; while(true){iv=System.in.read(); System.out.println(iv); } }Atsisiųskite, sukompiliuokite ir išbandykite programą.
public class SystInOut { public static void main (String [] args) throws Exception {int iv; String st=""; while(true){iv=System.in.read(); System.out.println((char)iv+": "+iv );} } }Ar negalėtume naudodamiesi vien srautu System.in pasiekti, kad surinkę, pavyzdžiui, klaviatūroje 123 programai perduotume ne trijų simbolių kodus, bet skaičių 123? Galime. Štai pavyzdys:
public class SystInOut1 { public static void main (String [] args) throws Exception {int iv; String st=""; while ((iv=System.in.read())!=13) st=st+(char)iv; iv=Integer.parseInt(st); System.out.println(iv); System.in.read(); }}Atsisiųskite, sukompiliuokite ir išbandykite programą.
BufferedReader br = new BufferedReader ( new InputStreamReader (System.in));Jomis iš pradinio srauto System.in suformuojamas toks įvedimo srautas, kad mes juo naudodamiesi galime programai perduoti duomenis ne baitas po baito, bet visą įvedamą simbolių visumą. Be to įvedimui paspartinti sukuriamas buferis - vidinės atminties sritis, kurioje formuojama įvedamų duomenų visuma.
java InOutFiles failo_vardasIki šiol rašėme tik tokias programas, kurioms nereikdavo nurodyti parametrų. Tačiau visada pagrindinio metodo aprašymą pradėdavome taip
public static void main (String args[]) {...}Tai reiškia, kad į pagrindinį metodą gali būti kreipiamasi nurodant String tipo argumentus; jie programoje interpretuojami kaip argumentų masyvo args[] elementai. Mūsų atveju tėra tik vienas šio masyvo elementas - failo, iš kurio įvesime duomenis vardas.
import java.io.*; public class InOutFiles { public static void main (String args [] )throws IOException {if (args.length!=1) Tikrina, ar nurodytas tik vienas argumentas {System.out.println("Reikia nurodyti failo varda!"); return;} Jeigu argumentas ne vienas, išveda įspėjimą try{ InputStream ived = new FileInputStream(args[0]);Sukuria įvedimo iš failo srautą int sk = ived.available(); Suranda, kiek baitų yra faile byte mas[]= new byte[sk]; Kiek yra baitų, tiek bus masyvo elementų ived.read(mas); Srautas skaito baitą po baito ir priskiria masyvo elementams String eil = new String (mas); Iš masyvo sukuriama viena eilutė System.out.println(eil); Eilutė išspausdinama ived.close();} Srautas uždaromas catch(IOException e) {} }}Atsisiųskite, sukompiliuokite ir išbandykite programą.
import java.io.*; public class InOutFiles { public static void main (String args [] )throws IOException {if (args.length!=2) {System.out.println("Reikia nurodyti failo varda!"); return;} try{ InputStream ived = new FileInputStream(args[0]); int sk = ived.available(); byte mas[]= new byte[sk]; ived.read(mas); String eil = new String (mas); System.out.println(eil); ived.close(); OutputStream isved = new FileOutputStream(args[1]); isved.write(mas); isved.close();} catch(IOException e) {} }}Programoje naudojome du duomenų srautus: vienas jų InputStream modifikacija skaitymui iš failų, kitas - OutputStream modifikacija rašymui į failus. Abu srautai ,,dirba" su baitais, t.y. skaito ar rašo baitas po baito. Panaudojome kelis šių srautų metodus. Jų yra ir daugiau. Apžvelgsime svarbiausius metodus lentelėje.
int available( ) | Nurodo, kiek galima perskaityti baitų. | void close( ) | Uždaro srautą | void mark (int N) | ,,Pažymi" baitą; prie šio baito galima bus sugrįžti, jeigu po pažymėjimo bus perskaityta nedaugiau N baitų. |
void reset( ) | Grįžta prie pažymėto baito | int read( ) | Perskaito sekantį baitą. Jeigo nėra ko skaityti, grąžina reikšmę -1. |
int read(byte [ ] b) | Perskaito iki b.length baitų į masyvą b;
grąžina perskaitytų baitų skaičių; jeigu pasiekia failo pabaigą, grąžina -1. |
int read (byte [ ] b, int n , int l) | Į masyvą b užrašo iki l baitų, n - pirmojo masyvo elemento, į kurį rašoma numeris. |
long skip (long l) | Praleidžia sraute (neskaito) l baitų. |
void close( ) | Uždaro srautą |
void flush( ) | Išsiunčia iš buferio visus ten esančius baitus | void write( ) | Užrašo sekantį baitą. | void write(byte [ ] b) | Užrašo baitų masyvą. | void write (byte [ ] b, int n , int l) | Užrašo masyvo b l baitų, pradedant n - uoju. |
public File (String kelias) public File (String kelias, String vardas)Iš aprašymo aišku, kad konstruktoriaus parametras - kelias prie failo, arba tas kelias į failo katalogą atskirai, o failo vardas atskirai. Jeigu nurodysime tik failo vardą, tai bus laikoma, kad failo reikia ieškoti darbiniame kataloge, t.y. tame pačiame kataloge, kaip ir pagrindinė programos klasė. Jeigu programoje sukuriame File klasės objektą tai dar nereiškia, kad failas ,,kūniškai" egzistuoja. Beje File klasės objektas nebūtinai yra failas, gali būti ir katalogas. Informaciją apie File klasės objektą galime gauti kreipdamiesi į jo metodus. Kokie yra metodai (dalis jų) ir kaip į juos kreipiamasi galite sužinoti iš šios programos.
import java.io.*; public class FilesMetodai { public static void main (String args[]) throws IOException { String fvardas,st; fvardas="FilesMetodai.java"; File f = new File(fvardas); System.out.println("Ar failas "+fvardas+ " egzistuoja?"); System.out.println(f.exists()); System.out.println("Gal tai katalogas?"); System.out.println(f.isDirectory()); System.out.println("Koks failo vardas?"); System.out.println(f.getName()); System.out.println("Koks kelias is darbinio katalogo prie failo?"); System.out.println(f.getPath()); System.out.println("Koks absoliutus kelias prie failo?"); System.out.println(f.getAbsolutePath()); System.out.println("Ar galima ji skaityti?"); System.out.println(f.canRead()); System.out.println("Ar galima i ji rasyti?"); System.out.println(f.canWrite()); System.out.println("Kada jis modifikuotas?"); System.out.println("Po "+f.lastModified()+ " milisekundziu nuo 1970 metu sausio 1 dienos"); System.out.println("Koks jo dydis baitais?"); System.out.println(f.length()); }}Atsisiųskite, sukompiliuokite ir įvykdykite programą. Modifikuokite ją taip, kad nagrinėjamo failo vardą galėtumėte įvesti kaip programos paleidimo parametrą.
File f = new File ("failas"); try {f.createNewFile();} catch (IOException e) {}Gali atsitikti, kad failo nepavyks sukurti, todėl reikia numatyti, kaip turi būti reaguojama į tokią išimtinę situaciją (net jeigu reagavimas reikštų, kad nebus jokio reagavimo).
File kat = new File ("katalogas"); try {kat.mkdir();} catch (IOException e) {}
fvardas = ".";
String [] list()patalpina į String tipo duomenų masyvą katalogo failų vardus. Štai pavyzdys:
import java.io.*; public class Files { public static void main (String args[]) throws IOException { File d = new File("."); String vard [] = d.list(); System.out.println(vard.length); for (int i=0; i<vard.length; i++) System.out.println(vard[i]); }}Atsisiųskite, sukompiliuokite ir įvykdykite programą.
import java.io.*; public class FilesFiltr { File d = new File("."); String sarasas []; public static void main (String args[]) throws IOException { new FilesFiltr();} FilesFiltr () { String sarasas [] = d.list(new Filtras ()); for (int i=0; i<sarasas.length; i++) System.out.println(sarasas[i]); } class Filtras implements FilenameFilter{ public boolean accept (File f, String vard) {return vard.endsWith("java");} }}Atsisiųskite, sukompiliuokite ir įvykdykite programą. Šioje programoje filtras tai klasės Filtras objektas. Šioje klasėje yra tik vienas metodas - accept. Jis grąžina reikšmę true, kai failas su vardu vard yra įtraukiamas į sąrašą. O jis įtraukiamas tada, kai eilutė vard baigiasi "java". Žinoma, galima metodą apibrėžti ir kitaip. Pavyzdžiui, galima tikrinti, ar failo vardas prasideda didžiąja (mažąja) raide ir taip toliau.
public FileReader (String fizinio_failo_vardas) public FileReader (File java_File_objekto_vardas)Šie konstruktoriai skiriasi tuo, kad pirmuoju atveju nurodome failo, kuris ,,kūniškai" egzistuoja kompiuterio atmintyje vardą, o antruoju - atitinkamo File klasės objekto vardas.
public FileWriter (String fizinio_failo_vardas) public FileWriter (String fizinio_failo_vardas, boolean prirasyti) public FileWriter (File java_File_objekto_vardas)Jeigu antrajame konstruktoriuje loginio kintamojo prirasyti reikšmė yra true tai rašant į failą, duomenys pridedami prie jau užrašytų duomenų.
FileReader skait = new FileReader( fizinio failo ar java objekto vardas ); BufferedReader bufskait = new BufferedReader(skait); FileWriter ras = new FileWriter( fizinio failo ar java objekto vardas ); BufferedWriter bufras = new BufferedWriter(ras);arba dar trumpiau, sujungiant dvi eilutes į vieną:
BufferedReader bufskait = new BufferedReader (new FileReader( fizinio failo ar java objekto vardas ) ); BufferedWriter bufras = new BufferedWriter (new FileWriter( fizinio failo ar java objekto vardas ));Naudojant buferizuotus srautus, galima duomenis iš failo skaityti eilutėmis. Metodas
readLine()nuskaito eilinę eilutę iš failo. Taigi eilutę iš failo su buferizuotu srautu bufskait galime perskaityti taip:
bufskait.readLine();Naudojant buferizuotą rašymo srautą į failą duomenis taip pat galime rašyti eilutėmis. Norėdami, kad kiti duomenys būtų rašomi naujoje eilutėje, turime įrašyti perėjimo į naują eilutę simbolį. Tai atlieka metodas
public void newLine();Taigi užrašyti eilutę į failą ir pereiti į kitą eilutę su srautu bufras galime taip:
bufras.write(eilutė); bufras.newLine()