CodeGym /Java Blog /Willekeurig /Lezen vanaf het toetsenbord: "lezers"
John Squirrels
Niveau 41
San Francisco

Lezen vanaf het toetsenbord: "lezers"

Gepubliceerd in de groep Willekeurig
Hoi! De lessen en taken in niveau 3 hebben je geleerd hoe je dingen op de console kunt weergeven en, in de andere richting, hoe je gegevens van het toetsenbord kunt lezen.
Lezen vanaf het toetsenbord: "lezers" - 1
Je hebt zelfs geleerd om de volgende complexe constructie te gebruiken om dit te bereiken:

BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
Maar er is één vraag die we nog niet hebben beantwoord.

Hoe werkt dit in hemelsnaam?

In werkelijkheid zijn programma's zelden volledig onafhankelijk. Ze communiceren met andere programma's, systemen, internet enz. Met "communiceren" bedoelen we vooral "gegevens uitwisselen". Dat wil zeggen, ze ontvangen wat externe gegevens en sturen ook ergens interne programmagegevens naar toe. Voorbeelden van programma's die gegevens uitwisselen zijn er genoeg in het dagelijks leven. Op veel websites kunt u bijvoorbeeld inloggen met uw Facebook- of Twitter-account in plaats van u te registreren. In deze situatie wisselen twee programma's (bijvoorbeeld Twitter en de website waarop u zich aanmeldt) de benodigde gegevens uit. Het uiteindelijke resultaat is dat u succesvol bent ingelogd. Het woord "stream"wordt gebruikt om het proces van gegevensuitwisseling te beschrijven. Waar komt deze naam vandaan? In uw ervaring kan een "stroom" meer geassocieerd worden met rivieren en dan met programmeren. Dat is geen toeval :) Een stream is in wezen een bewegend stukje data. Met andere woorden, bij het programmeren stroomt geen water, maar gegevens in de vorm van bytes en tekens. We kunnen stukjes data uit een datastroom ontvangen en die vervolgens gebruiken. Nogmaals, we gebruiken de water/stroom-analogie: je kunt water uit een rivier scheppen om soep te maken, een vuur te blussen of je bloemen water te geven. Met Streams kunt u met elke gegevensbron werken: of het nu internet, het bestandssysteem van uw computer of iets anders is - het maakt geen verschil. Streams zijn een universeel hulpmiddel. Ze stellen een programma in staat om overal vandaan gegevens te ontvangen (invoerstromen) en deze overal te verzenden (uitvoerstromen). Hun taak is hetzelfde: gegevens van de ene plaats halen en naar een andere sturen. Er zijn twee soorten stromen:
  1. Input streams worden gebruikt om data te ontvangen
  2. Uitvoerstromen zijn voor het verzenden van gegevens.
In Java worden deze streams geïmplementeerd door de klassen InputStreamen OutputStream. Maar de streams kunnen op een andere manier worden gecategoriseerd. Naast input- en outputstreams spreken we ook wel van bytestreams en character streams . De betekenis hier zou duidelijk genoeg moeten zijn: bytestream verzendt informatie als een set bytes, terwijl een karakterstream deze verzendt als een set tekens. In deze les staan ​​we stil bij invoerstromen. Aan het einde van de les plaats ik een link met informatie over outputstromen. Je kunt het zelf lezen :) Bekijk nu deze code:

BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
Vond je deze zin niet behoorlijk intimiderend toen je de lessen doornam? :) Dat zal niet het geval zijn als we eenmaal hebben onderzocht hoe het werkt. Laten we de zaken rechtzetten. We beginnen bij het einde. System.inis een InputStreamobject, een instantie van de klasse waarover we eerder spraken. Het is een invoerstroom die is gekoppeld aan een systeeminvoerapparaat (het toetsenbord). Overigens ben je indirect bekend met deze stream. U gebruikt tenslotte vaak zijn "collega" - System.out! System.outis de uitvoerstroom van het systeem . Het wordt gebruikt om gegevens naar de console uit te voeren via uw favoriete methode System.out.println(), die u constant gebruikt :) System.outis een stream voor het verzenden van gegevens naar de console, terwijlSystem.inis om gegevens van het toetsenbord te krijgen. Het is allemaal eenvoudig :) Bovendien kunnen we gegevens van het toetsenbord lezen zonder deze enorme constructie. We kunnen gewoon schrijven: System.in.read();

public class Main {

   public static void main(String[] args) throws IOException {

       while (true) {
           int x = System.in.read();
           System.out.println(x);
       }
   }
}
De InputStreamklasse (onthoud, System.inis een InputStreamobject) heeft een read()methode waarmee u gegevens kunt lezen. Er is één probleem: het leest bytes , geen karakters . Het is saai om alleen Engelse letters te gebruiken, dus laten we proberen het Chinese karakter "魚" van het toetsenbord te lezen (kopieer deze letter van hier en plak hem in de console met ctrl + v op pc of Command + v op Mac ) . Dit karakter betekent trouwens 'een vis'. Console-uitgang: 233 173 154 10 Dit symbool en veel andere Chinezen nemen 3 bytes in beslag in het geheugen van de computer (in tegenstelling tot Latijnse letters, die slechts 1 byte in beslag nemen). In dit geval worden 4 bytes uit de stream gelezen: de eerste drie vertegenwoordigen het teken "魚", en de andere byte vertegenwoordigt een nieuwe regel (Enter). Dienovereenkomstig System.inis in zijn onopgesmukte vorm geen optie voor ons. Mensen (met zeldzame uitzonderingen!) weten niet hoe ze bytes moeten lezen. Maar de InputStreamReaderklas schiet te hulp! Laten we eens kijken wat voor dier dit is.

BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
We gaan door System.innaar het InputStreamReader- object. De naam van de klas zegt het al! We maken een InputStreamReaderobject en geven het een invoerstroom door waaruit het gegevens zal lezen. In dit geval...

new InputStreamReader(System.in)
... we vertellen het, "u zult gegevens lezen van de systeeminvoerstroom (van het toetsenbord)". Maar dit is niet de enige functie! De InputStreamReaderontvangt niet alleen gegevens van de stream. Het converteert ook bytestreams naar karakterstreams . Met andere woorden, u hoeft de gegevens niet langer om te zetten van "enen en nullen" naar een "door mensen leesbare taal". InputStreamreaderdoet alles voor je. Is natuurlijk InputStreamReaderniet beperkt tot het lezen van gegevens van de console. Het kan ook gegevens van andere plaatsen lezen. Bijvoorbeeld vanuit een bestand:

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;

public class Main {

   public static void main(String[] args) throws IOException {
       InputStreamReader inputStreamReader = new InputStreamReader(new FileInputStream("C:\\Users\\username\\Desktop\\testFile.txt"));
   }
}
Hier maken we een FileInputStream(één smaak van InputStream), geven we het bestandspad door en geven we de stream zelf door aan de InputStreamReader. Nu kan het gegevens uit het bestand lezen (als er natuurlijk een bestand op het pad staat). We gebruiken ook de methode InputStreamReadervan de klasse om gegevens te lezen (de bron van de gegevens doet er niet toe: de console, een bestand of ergens anders). read()Wat is het verschil tussen System.in.read()en InputStreamReader.read()?\ Laten we opnieuw proberen het karakter "魚" te lezen met een InputStreamReader. Ik herinner u aan wat eigenlijk is gelezen door System.in.read(): 233 173 154 10 En hoe werkt InputStreamReaderhetzelfde?

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);
       }
   }
}
Console output: 39770 10 Het verschil is meteen duidelijk. De laatste byte (die de nieuwe regel vertegenwoordigt) blijft ongewijzigd (het getal 10), maar het teken "魚" is omgezet in een enkele code "39770". Dit is wat het betekent om karakters te lezen! Als je niet gelooft dat 39770 de letter "魚" vertegenwoordigt, kun je jezelf gemakkelijk overtuigen :)
import java.io.IOException;

public class Main {

   public static void main(String[] args) throws IOException {

       char x = 39770;
       System.out.println(x);
   }
}
Console-uitvoer: Maar als het zo geweldigInputStreamReader is, waarom hebben we dan ook BufferedReader? InputStreamReaderweet hoe gegevens te lezen en bytes om te zetten in tekens. Wat kunnen we nog meer vragen? Waarom een ​​andere lezer? :/ Het antwoord is heel eenvoudig: voor betere prestaties en gemak . Laten we beginnen met de prestaties. Wanneer BufferedReadergegevens worden gelezen, gebruikt het een speciaal gebied dat een buffer wordt genoemd, waar het de gelezen tekens "opslaat". Als deze karakters nodig zijn in het programma, worden ze uiteindelijk uit de buffer gehaald, niet rechtstreeks uit de gegevensbron (toetsenbord, bestand, enz.). Dit bespaart veel middelen. Om te begrijpen hoe dit werkt, stel je je een koerier voor in een groot bedrijf. De koerier zit in een kantoor te wachten tot iemand pakketten komt brengen voor bezorging. Elke keer dat hij een nieuw pakket ontvangt, kan hij meteen op pad. Maar er kunnen overdag veel pakketten zijn. Hij zou veel moeten reizen tussen het kantoor en de afleveradressen. In plaats daarvan zet de koerier een doos in zijn kantoor. Iedereen stopt zijn pakjes in de doos. Nu kan de koerier rustig de doos pakken en van adres naar adres gaan. Dit scheelt veel tijd, want hij hoeft niet elke keer terug naar kantoor. In dit voorbeeld is de box slechts een buffer en is het kantoor een gegevensbron. Het is voor de koerier veel gemakkelijker om pakketten uit een enkele doos te halen bij het bezorgen dan om elke keer terug naar kantoor te gaan. Hij zal ook benzine besparen. Evenzo is het in een programma veel minder arbeidsintensief om gegevens uit een buffer te halen dan om elke keer naar de gegevensbron te verwijzen. Als gevolg,BufferedReader+ InputStreamReaderis sneller dan InputStreamReaderalleen . We hebben de prestaties overwogen. Hoe zit het met het gemak? Het belangrijkste voordeel is dat het Bufferedreaderniet slechts één teken tegelijk kan lezen (hoewel het dit met zijn read()methode kan doen), maar ook hele regels tegelijk! Dit gebeurt aan de hand van de readLine()methode;

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("We read this line from the keyboard:");
       System.out.println(s);
   }
}
Console-uitvoer: CodeGym is de beste website om Java te leren! We lezen deze regel van het toetsenbord: CodeGym is de beste website om Java te leren! Dit is vooral handig bij het lezen van grote hoeveelheden gegevens. Een of twee regels tekst karakter voor karakter lezen is nog steeds haalbaar. Maar letter voor letter in "Oorlog en vrede" lezen zou enigszins problematisch zijn :)
Opmerkingen
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION