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
BufferedReadersokszor. 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.incsak 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.innem túl kényelmes. A cirill (és egyéb) betűk helyes olvasásához használjuk InputStreamReaderburkoló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
InputStreamReaderké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 BufferedReaderegy 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 BufferedReaderjellemzője és előnye a hagyományoshoz képest InputStreamReadera 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
Természetesen BufferedReadernagyon 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, azSystemosztálynak két statikus mezője van – System.inés System.out. Ezek az ikertestvérek stream objektumok. System.inegy InputStream. És System.out egy PrintStream. Mindjárt beszélünk róla System.out. Ha belépünk az Systemosztá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 outváltozó egy PrintStreamhivatkozá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.outnem további olvasói és írói osztályok használatával? Valóban az :) És megtehetjük, bár a System.outváltozót a módosítóval jelöljük final!
Tehát mire van szükségünk, hogy ez megtörténjen? Először is szükségünk van egy új PrintStreamobjektumra a jelenlegi helyére. Az aktuális objektum, beállítva aSystemosztá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 Systemosztály rendelkezik a szükséges módszerrel: setOut(). Elvesz egy PrintStreamobjektumot, é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