Szia! A mai lecke a kényelem kedvéért két részre oszlik. Megismételünk néhány régi témát, amelyeket korábban érintettünk, és megfontolunk néhány új funkciót :) Kezdjük az elsővel. Már van egy osztályod, mint
Természetesen
Tehát mire van szükségünk, hogy ez megtörténjen? Először is szükségünk van egy új
BufferedReader
sokszor. Remélem, nem volt ideje elfelejteni ezt a kijelentést:
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
Mielőtt tovább olvasná, próbálja meg emlékezni, hogy az egyes összetevők – System.in
, InputStreamReader
, BufferedReader
– miért felelősek, és miért van rájuk szükség. Emlékeztél? Ha nem, semmi gond. :) Ha valamit elfelejtettél, olvasd el újra ezt a leckét , ami az olvasóóráknak szól. Röviden felidézzük, mire képesek mindegyikük. System.in
— ez egy adatfolyam a billentyűzetről történő fogadáshoz. Elvileg ez önmagában elég lenne a szövegolvasáshoz szükséges logika megvalósításához. De, mint emlékszel, System.in
csak bájtokat tud olvasni, karaktereket nem:
public class Main {
public static void main(String[] args) throws IOException {
while (true) {
int x = System.in.read();
System.out.println(x);
}
}
}
Ha végrehajtjuk ezt a kódot és beírjuk a cirill "Й" betűt, a kimenet a következő lesz:
Й
208
153
10
A cirill karakterek 2 bájtot foglalnak el a memóriában, és megjelennek a képernyőn. A 10-es szám egy soremelés karakterének decimális ábrázolása, azaz az Enter megnyomásától. A bájtok olvasása nagy élvezet, ezért a használata System.in
nem túl kényelmes. A cirill (és egyéb) betűk helyes olvasásához használjuk InputStreamReader
burkolóként:
public class Main {
public static void main(String[] args) throws IOException {
InputStreamReader reader = new InputStreamReader(System.in);
while (true) {
int x = reader.read();
System.out.println(x);
}
}
}
Ugyanazt az "Й" betűt írjuk be, de az eredmény ezúttal más:
Й
1049
10
InputStreamReader
két bájtot (208 és 153) konvertált egyetlen 1049-es számmá. Ezt jelenti a karakterek olvasása. Az 1049 a cirill "Й" betűnek felel meg. Könnyen meggyőzhetjük magunkat, hogy ez igaz:
public class Main {
public static void main(String[] args) throws IOException {
char x = 1049;
System.out.println(x);
}
}
Konzol kimenet:
Й
És ahogy forBufferedReader
(és általában, BufferedAnythingYouWant
), pufferelt osztályokat használnak a teljesítmény optimalizálására. Egy adatforrás (fájl, konzol, webes erőforrás) elérése teljesítmény szempontjából meglehetősen költséges. Ezért a hozzáférések számának csökkentése érdekében BufferedReader
egy speciális pufferben olvassa be és gyűjti az adatokat, és onnan kapjuk meg. Ennek eredményeként az adatforráshoz való hozzáférések száma csökken – akár több nagyságrenddel is! Egy másik BufferedReader
jellemzője és előnye a hagyományoshoz képest InputStreamReader
a rendkívül hasznos readLine()
módszer, amely egész adatsorokat olvas ki, nem pedig egyes számokat. Ez természetesen rendkívül kényelmes nagy szövegek kezelésekor. Így néz ki a sorok olvasása:
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
String s = reader.readLine();
System.out.println ("The user entered the following text:");
System.out.println(s);
reader.close();
}
}
BufferedReader+InputStreamReader is faster than InputStreamReader alone
The user entered the following text:
BufferedReader+InputStreamReader is faster than InputStreamReader alone

BufferedReader
nagyon rugalmas. Nem korlátozódhat a billentyűzet használatára. Például adatokat olvashat közvetlenül az internetről, egyszerűen átadja a szükséges URL-t egy olvasónak:
public class URLReader {
public static void main(String[] args) throws Exception {
URL oracle = new URL("https://www.oracle.com/index.html");
BufferedReader in = new BufferedReader(
new InputStreamReader(oracle.openStream()));
String inputLine;
while ((inputLine = in.readLine()) != null)
System.out.println(inputLine);
in.close();
}
}
A fájlból a fájl elérési útjának átadásával olvashat adatokat:
public class Main {
public static void main(String[] args) throws Exception {
FileInputStream fileInputStream = new FileInputStream("testFile.txt");
BufferedReader reader = new BufferedReader(new InputStreamReader(fileInputStream));
String str;
while ((str = reader.readLine()) != null) {
System.out.println (str);
}
reader.close();
}
}
A System.out cseréje
Most pedig vessünk egy pillantást egy érdekes képességre, amelyhez korábban még nem foglalkoztunk. Mint biztosan emlékszel, azSystem
osztálynak két statikus mezője van – System.in
és System.out
. Ezek az ikertestvérek stream objektumok. System.in
egy InputStream
. És System.out
egy PrintStream
. Mindjárt beszélünk róla System.out
. Ha belépünk az System
osztály forráskódjába, ezt látjuk:
public final class System {
……………...
public final static PrintStream out = null;
…………
}
Így System.out
egyszerűen az osztály szokásos statikus változójaSystem
. Nincs benne semmi varázslat :) A out
változó egy PrintStream
hivatkozás. Íme egy érdekes kérdés: Mikor System.out.println()
fut, miért pont a kimenet a konzolra megy, és nem valahova máshova? És ezen lehet valahogy változtatni? Tegyük fel például, hogy adatokat szeretnénk beolvasni a konzolról, és szöveges fájlba írni. Lehetséges-e ezt valahogyan megvalósítani egyszerűen System.out
nem további olvasói és írói osztályok használatával? Valóban az :) És megtehetjük, bár a System.out
változót a módosítóval jelöljük final
! 
PrintStream
objektumra a jelenlegi helyére. Az aktuális objektum, beállítva aSystem
osztály alapértelmezés szerint nem szolgálja céljainkat: a konzolra mutat. Létre kell hoznia egy újat, amely egy szöveges fájlra mutat – az adataink „célállomására”. Másodszor, meg kell értenünk, hogyan rendelhetünk új értéket a változóhoz System.out
. Nem használhat egyszerű hozzárendelési operátort, mert a változó meg van jelölve final
. Dolgozzunk visszafelé a végétől. Amint megtörténik, az System
osztály rendelkezik a szükséges módszerrel: setOut()
. Elvesz egy PrintStream
objektumot, és beállítja a kimenet célhelyeként. Pont erre van szükségünk! Már csak egy tárgy létrehozása van hátra PrintStream
. Ez is egyszerű:
PrintStream filePrintStream = new PrintStream(new File("C:\\Users\\Username\\Desktop\\test.txt"));
A teljes kód így fog kinézni:
public class SystemRedirectService {
public static void main(String arr[]) throws FileNotFoundException
{
PrintStream filePrintStream = new PrintStream(new File("C:\\Users\\Username\\Desktop\\test.txt"));
/* Save the current value of System.out in a separate variable so that later
we can switch back to console output */
PrintStream console = System.out;
// Assign a new value to System.out
System.setOut(filePrintStream);
System.out.println("This line will be written to the text file");
// Restore the old value of System.out
System.setOut(console);
System.out.println("But this line will be output to the console!");
}
}
Ennek eredményeként az első karakterlánc beíródik a szövegfájlba, a második pedig megjelenik a konzolban :) Ezt a kódot bemásolhatod az IDE-be és futtathatod. Nyisd meg a szöveges fájlt, és látni fogod, hogy a sztringet sikerült odaírni :) Ezzel a leckénk a végére ért. Ma felidéztük, hogyan kell dolgozni a streamekkel és az olvasókkal. Felidéztük, hogy miben különböznek egymástól, és megismerkedtünk néhány új képességgel System.out
, amelyeket szinte minden leckén használtunk :) A következő órákig!
További olvasnivalók: |
---|
GO TO FULL VERSION