Hej! Dagens lektion kommer att delas upp i två delar för enkelhetens skull. Vi kommer att upprepa några gamla ämnen som vi berörde tidigare, och vi kommer att överväga några nya funktioner :) Låt oss börja med den första. Du har redan en klass som
Naturligtvis
Så vad behöver vi för att få detta att hända? Först och främst behöver vi ett nytt
BufferedReader
många gånger. Jag hoppas att du inte har haft tid att glömma detta uttalande:
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
Innan du läser vidare, försök komma ihåg vad varje komponent — , , System.in
— InputStreamReader
är BufferedReader
ansvarig för och varför den behövs. Kom du ihåg? Om inte, inga bekymmer. :) Om du har glömt något, läs om den här lektionen , som är tillägnad läsarklasser. Vi kommer kort att komma ihåg vad var och en av dem kan göra. System.in
— det här är en ström för att ta emot data från tangentbordet. I princip skulle det ensamt vara tillräckligt för att implementera den logik som krävs för att läsa text. Men, som du kommer ihåg, System.in
kan bara läsa bytes, inte tecken:
public class Main {
public static void main(String[] args) throws IOException {
while (true) {
int x = System.in.read();
System.out.println(x);
}
}
}
Om vi kör den här koden och anger den kyrilliska bokstaven "Й", blir utdata:
Й
208
153
10
Kyrilliska tecken upptar 2 byte i minnet och de visas på skärmen. Siffran 10 är decimalrepresentationen av ett radmatningstecken, dvs från att trycka på Enter. Att läsa bytes är ett sånt nöje, så att använda System.in
är inte särskilt bekvämt. För att korrekt läsa kyrilliska (och andra) bokstäver använder vi InputStreamReader
som omslag:
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);
}
}
}
Vi skriver in samma bokstav "Й", men resultatet är annorlunda den här gången:
Й
1049
10
InputStreamReader
konverterade två byte (208 och 153) till det enda talet 1049. Detta är vad det innebär att läsa tecken. 1049 motsvarar den kyrilliska bokstaven "Й". Vi kan lätt övertyga oss själva om att detta är sant:
public class Main {
public static void main(String[] args) throws IOException {
char x = 1049;
System.out.println(x);
}
}
Konsolutgång:
Й
Och som forBufferedReader
(och i allmänhet, BufferedAnythingYouWant
) används buffrade klasser för att optimera prestanda. Att komma åt en datakälla (fil, konsol, webbresurs) är ganska dyrt när det gäller prestanda. Därför, för att minska antalet åtkomster, BufferedReader
läser och samlar vi data i en speciell buffert, och vi får det därifrån. Som ett resultat minskas antalet gånger datakällan har åtkomst - möjligen i flera storleksordningar! En annan av BufferedReader
funktionerna och dess fördel gentemot den vanliga , InputStreamReader
är den extremt hjälpsamma readLine()
metoden, som läser hela rader med data, inte enskilda siffror. Detta är förstås superbekvämt när man har att göra med stora texter. Så här ser läsrader ut:
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
är mycket flexibel. Du är inte begränsad till att arbeta med tangentbordet. Du kan till exempel läsa data direkt från webben, helt enkelt genom att skicka den nödvändiga webbadressen till en läsare:
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();
}
}
Du kan läsa data från en fil genom att skicka filsökvägen:
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();
}
}
Byter ut System.out
Låt oss nu ta en titt på en intressant förmåga som vi inte har berört tidigare. Som du säkert kommer ihågSystem
har klassen två statiska fält - System.in
och System.out
. Dessa tvillingbröder är strömobjekt. System.in
är en InputStream
. Och System.out
är en PrintStream
. Just nu ska vi prata om System.out
. Om vi hamnar i System
klassens källkod ser vi detta:
public final class System {
……………...
public final static PrintStream out = null;
…………
}
Det är alltså System.out
helt enkelt en vanlig statisk variabel iSystem
klassen. Det är inget magiskt med det :) out
Variabeln är en PrintStream
referens. Här är en intressant fråga: När System.out.println()
exekveras, varför går utdata till konsolen och inte någon annanstans? Och kan detta ändras på något sätt? Anta till exempel att vi vill läsa data från konsolen och skriva det till en textfil. Är det möjligt att på något sätt implementera detta helt enkelt med System.out
istället för ytterligare läsar- och skribentklasser? Det är det faktiskt :) Och vi kan göra det även om System.out
variabeln är markerad med final
modifieraren! 
PrintStream
objekt för att ersätta det nuvarande. Det aktuella objektet, satt iSystem
klass som standard, tjänar inte våra syften: den pekar på konsolen. Du måste skapa en ny som pekar på en textfil — "destinationen" för vår data. För det andra måste vi förstå hur man tilldelar ett nytt värde till variabeln System.out
. Du kan inte använda en enkel tilldelningsoperator, eftersom variabeln är markerad final
. Låt oss arbeta baklänges från slutet. Som det händer System
har klassen metoden vi behöver: setOut()
. Den tar ett PrintStream
objekt och ställer in det som destination för utmatning. Det är precis vad vi behöver! Allt som återstår är att skapa ett PrintStream
objekt. Detta är också enkelt:
PrintStream filePrintStream = new PrintStream(new File("C:\\Users\\Username\\Desktop\\test.txt"));
Hela koden kommer att se ut så här:
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!");
}
}
Som ett resultat skrivs den första strängen till textfilen och den andra visas i konsolen :) Du kan kopiera den här koden till din IDE och köra den. Öppna textfilen så ser du att strängen har skrivits där :) Med detta har vår lektion kommit till slutet. Idag kom vi ihåg hur man arbetar med strömmar och läsare. Vi kom ihåg hur de skiljer sig från varandra och lärde oss om några nya funktioner i , System.out
som vi har använt i nästan varje lektion :) Tills nästa lektion!
Mer läsning: |
---|
GO TO FULL VERSION