Hej! Dagens lektion vil for nemheds skyld blive opdelt i to dele. Vi gentager nogle gamle emner, som vi har berørt tidligere, og vi vil overveje nogle nye funktioner :) Lad os starte med den første. Du har allerede en klasse som
Det er selvfølgelig
Så hvad har vi brug for for at få det til at ske? Først og fremmest har vi brug for et nyt
BufferedReader
mange gange. Jeg håber ikke du har haft tid til at glemme denne udtalelse:
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
Inden du læser videre, prøv at huske, hvad hver komponent — System.in
, InputStreamReader
, BufferedReader
— er ansvarlig for, og hvorfor den er nødvendig. Huskede du det? Hvis ikke, ingen bekymringer. :) Hvis du har glemt noget, så genlæs denne lektion , som er dedikeret til læserklasser. Vi vil kort huske, hvad hver af dem kan. System.in
— dette er en stream til modtagelse af data fra tastaturet. I princippet ville det alene være nok til at implementere den logik, der kræves for at læse tekst. Men, som du vil huske, System.in
kan kun læse bytes, ikke tegn:
public class Main {
public static void main(String[] args) throws IOException {
while (true) {
int x = System.in.read();
System.out.println(x);
}
}
}
Hvis vi udfører denne kode og indtaster det kyrilliske bogstav "Й", vil outputtet være:
Й
208
153
10
Kyrilliske tegn optager 2 bytes i hukommelsen, og de vises på skærmen. Tallet 10 er decimalrepræsentationen af et linjeskifttegn, dvs. ved at trykke på Enter. At læse bytes er sådan en fornøjelse, så System.in
det er ikke særlig praktisk at bruge. For at kunne læse kyrilliske (og andre) bogstaver korrekt, bruger vi InputStreamReader
som indpakning:
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 indtaster det samme bogstav "Й", men resultatet er anderledes denne gang:
Й
1049
10
InputStreamReader
konverteret to bytes (208 og 153) til det enkelte tal 1049. Dette er, hvad det vil sige at læse tegn. 1049 svarer til det kyrilliske bogstav "Й". Vi kan nemt overbevise os selv om, at dette er sandt:
public class Main {
public static void main(String[] args) throws IOException {
char x = 1049;
System.out.println(x);
}
}
Konsoludgang:
Й
Og som forBufferedReader
(og generelt BufferedAnythingYouWant
), bruges bufferklasser til at optimere ydeevnen. Adgang til en datakilde (fil, konsol, webressource) er ret dyrt med hensyn til ydeevne. Derfor, for at reducere antallet af adgange, BufferedReader
læser og akkumulerer data i en særlig buffer, og vi får det derfra. Som et resultat skæres antallet af gange, datakilden tilgås, ned - muligvis i flere størrelsesordener! En anden af BufferedReader
funktionerne og dens fordel i forhold til den almindelige InputStreamReader
, er den yderst hjælpsomme readLine()
metode, som læser hele datalinjer, ikke individuelle tal. Dette er selvfølgelig super praktisk, når man har med store tekster at gøre. Sådan ser læselinjer ud:
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
meget fleksibelt. Du er ikke begrænset til at arbejde med tastaturet. For eksempel kan du læse data direkte fra nettet ved blot at videregive den nødvendige URL til en læser:
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æse data fra en fil ved at videregive filstien:
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();
}
}
Udskiftning af System.out
Lad os nu tage et kig på en interessant egenskab, som vi ikke har berørt før. Som du sikkert husker,System
har klassen to statiske felter - System.in
og System.out
. Disse tvillingebrødre er strømobjekter. System.in
er en InputStream
. Og System.out
er en PrintStream
. Lige nu taler vi om System.out
. Hvis vi falder ind i System
klassens kildekode, ser vi dette:
public final class System {
……………...
public final static PrintStream out = null;
…………
}
Således System.out
er simpelthen en almindelig statisk variabel iSystem
klassen. Der er ikke noget magisk over det :) Variablen out
er en PrintStream
reference. Her er et interessant spørgsmål: Hvornår System.out.println()
udføres, hvorfor går outputtet præcist til konsollen og ikke et andet sted? Og kan dette ændres på en eller anden måde? Antag for eksempel, at vi vil læse data fra konsollen og skrive dem til en tekstfil. Er det muligt på en eller anden måde at implementere dette blot ved at bruge System.out
i stedet for yderligere læser- og forfatterklasser? Det er det faktisk :) Og vi kan gøre det, selvom variablen System.out
er markeret med final
modifikatoren! 
PrintStream
objekt til at erstatte det nuværende. Det aktuelle objekt, sat iSystem
klasse som standard, tjener ikke vores formål: det peger på konsollen. Du skal oprette en ny, der peger på en tekstfil — "destinationen" for vores data. For det andet skal vi forstå, hvordan man tildeler en ny værdi til variablen System.out
. Du kan ikke bruge en simpel tildelingsoperator, fordi variablen er markeret final
. Lad os arbejde baglæns fra slutningen. Som det sker, System
har klassen den metode, vi har brug for: setOut()
. Den tager et PrintStream
objekt og sætter det som destination for output. Det er lige hvad vi har brug for! Tilbage er kun at skabe et PrintStream
objekt. Dette er også nemt:
PrintStream filePrintStream = new PrintStream(new File("C:\\Users\\Username\\Desktop\\test.txt"));
Den fulde kode vil se sådan ud:
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 et resultat bliver den første streng skrevet til tekstfilen, og den anden vises i konsollen :) Du kan kopiere denne kode ind i din IDE og køre den. Åbn tekstfilen, og du vil se, at strengen er blevet skrevet der :) Med dette er vores lektion nået til ende. I dag mindede vi om, hvordan man arbejder med streams og læsere. Vi huskede, hvordan de adskiller sig fra hinanden og lærte om nogle nye funktioner i System.out
, som vi har brugt i næsten hver lektion :) Indtil de næste lektioner!
Mere læsning: |
---|
GO TO FULL VERSION