CodeGym /Java-blogg /Tilfeldig /Leser fra tastaturet: "lesere"
John Squirrels
Nivå
San Francisco

Leser fra tastaturet: "lesere"

Publisert i gruppen
Hei! Leksjonene og oppgavene på nivå 3 lærte deg hvordan du viser ting på konsollen, og når du beveger deg i den andre retningen, hvordan du leser data fra tastaturet.
Lese fra tastaturet: "lesere" - 1
Du lærte til og med å bruke følgende komplekse konstruksjon for å oppnå dette:

BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
Men det er ett spørsmål vi ikke har besvart ennå.

Hvordan i all verden fungerer dette?

I virkeligheten er programmer sjelden helt uavhengige. De kommuniserer med andre programmer, systemer, internett osv. Med «kommunisere» mener vi hovedsakelig «utveksle data». Det vil si at de mottar noen eksterne data og sender også interne programdata et sted. Eksempler på programmer som utveksler data florerer i hverdagen. For eksempel lar mange nettsteder deg logge på med Facebook- eller Twitter-kontoen din i stedet for å registrere deg. I denne situasjonen utveksler to programmer (f.eks. Twitter og nettstedet du logger på) de nødvendige dataene. Det endelige resultatet er at du er logget på. Ordet "stream"brukes til å beskrive prosessen med datautveksling. Hvor kom dette navnet fra? Etter din erfaring kan en "bekk" være mer assosiert med elver og enn med programmering. Det er ingen tilfeldighet :) En strøm er i hovedsak et stykke data i bevegelse. Med andre ord, i programmering er det ikke vann som renner — men snarere data i form av byte og tegn. Vi kan motta biter av data fra en datastrøm og deretter bruke dem. Igjen, vi bruker vann/strøm-analogien: du kan øse vann fra en elv for å lage suppe, slukke brann eller vanne blomstene dine. Strømmer lar deg jobbe med hvilken som helst datakilde: enten Internett, datamaskinens filsystem eller noe annet – det spiller ingen rolle. Strømmer er et universelt verktøy. De lar et program motta data fra hvor som helst (inndatastrømmer) og sende dem hvor som helst (utdatastrømmer). Oppgaven deres er den samme: å ta data fra ett sted og sende det til et annet. Det er to typer strømmer:
  1. Inndatastrømmer brukes til å motta data
  2. Utdatastrømmer er for å sende data.
I Java implementeres disse strømmene av klassene InputStreamog OutputStream. Men strømmene kan kategoriseres på en annen måte. I tillegg til inngangs- og utdatastrømmer snakker vi også om bytestrømmer og karakterstrømmer . Betydningen her bør være klar nok: bytestrøm sender informasjon som et sett med byte, mens en tegnstrøm sender den som et sett med tegn. I denne leksjonen skal vi dvele ved inngangsstrømmer. Jeg legger en lenke med informasjon om utdatastrømmer på slutten av leksjonen. Du kan lese den på egen hånd :) Ta en titt på denne koden:

BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
Da du gikk gjennom leksjonene, syntes du ikke denne linjen var ganske skremmende? :) Det vil ikke være tilfelle når vi har utforsket hvordan det fungerer. La oss ordne opp. Vi starter på slutten. System.iner et InputStreamobjekt, en forekomst av klassen vi snakket om tidlig. Det er en inngangsstrøm koblet til en systeminndataenhet (tastaturet). Du er forresten indirekte kjent med denne strømmen. Tross alt bruker du ofte dens "kollega" - System.out! System.outer systemets utdatastrøm . Den brukes til å sende ut data til konsollen via din favorittmetode System.out.println(), som du bruker konstant :) System.outer en strøm for å sende data til konsollen, mensSystem.iner for å hente data fra tastaturet. Det hele er enkelt :) Dessuten kan vi lese data fra tastaturet uten denne enorme konstruksjonen. Vi kan ganske enkelt skrive: 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);
       }
   }
}
Klassen InputStream(husk, System.iner et InputStreamobjekt) har en read()metode som lar deg lese data. Det er ett problem: den leser byte , ikke tegn . Det er kjedelig å bare bruke engelske bokstaver, så la oss prøve å lese det kinesiske tegnet "魚" fra tastaturet (bare kopier denne bokstaven herfra og lim den inn på konsollen ved å bruke ctrl + v på PC eller Command + v på Mac). Denne karakteren betyr "en fisk" forresten. Konsollutgang: 233 173 154 10 Dette symbolet og mange andre kinesere opptar 3 byte i datamaskinens minne (i motsetning til latinske bokstaver, som bare opptar 1 byte). I dette tilfellet leses 4 byte fra strømmen: de tre første representerer tegnet "魚", og andre byte representerer en ny linje (Enter). Følgelig, System.ini sin usminkede form er ikke et alternativ for oss. Mennesker (med sjeldne unntak!) vet ikke hvordan de skal lese bytes. Men InputStreamReaderklassen kommer til unnsetning! La oss se hva slags dyr dette er.

BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
Vi går videre System.intil InputStreamReader- objektet. Klassenavnet sier det! Vi lager et InputStreamReaderobjekt og sender det en inngangsstrøm som det vil lese data fra. I dette tilfellet...

new InputStreamReader(System.in)
...vi forteller det, "du vil lese data fra systeminndatastrømmen (fra tastaturet)". Men dette er ikke den eneste funksjonen! Den InputStreamReadermottar ikke bare data fra strømmen. Den konverterer også bytestrømmer til karakterstrømmer . Du trenger med andre ord ikke lenger konvertere dataene fra "enere og nuller" til et "menneskelest språk". InputStreamreadergjør alt for deg. Selvfølgelig InputStreamReaderer det ikke begrenset til å lese data fra konsollen. Den kan også lese data fra andre steder. For eksempel fra en fil:

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"));
   }
}
Her lager vi en FileInputStream(en smak av InputStream), sender inn filbanen og sender selve strømmen til InputStreamReader. Nå vil den kunne lese data fra filen (hvis en fil faktisk eksisterer på banen, selvfølgelig). Vi bruker også InputStreamReaderklassens read()metode for å lese data (kilden til dataene spiller ingen rolle: konsollen, en fil eller et annet sted). Hva er forskjellen mellom System.in.read()og InputStreamReader.read()?\ La oss igjen prøve å lese tegnet "魚" med en InputStreamReader. Jeg minner deg om hva som faktisk ble lest av System.in.read(): 233 173 154 10 Og hvordan fungerer det InputStreamReadersamme?

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);
       }
   }
}
Konsoll utgang: 39770 10 Forskjellen er umiddelbart tydelig. Den siste byten (som representerer den nye linjen) forblir uendret (tallet 10), men tegnet "魚" ble konvertert til en enkelt kode "39770". Dette er hva det vil si å lese karakterer! Hvis du ikke tror at 39770 representerer bokstaven "魚", er det lett å overbevise deg selv :)
import java.io.IOException;

public class Main {

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

       char x = 39770;
       System.out.println(x);
   }
}
Konsollutgang: Men hvis InputStreamReaderdet er så bra, hvorfor trenger vi også BufferedReader? InputStreamReadervet hvordan man leser data og konverterer byte til tegn. Hva mer kan vi be om? Hvorfor en annen leser? :/ Svaret er veldig enkelt: for større ytelse og bekvemmelighet . La oss starte med ytelse. Når BufferedReaderden leser data, bruker den et spesielt område kalt en buffer, der den "lagrer" tegnene den leser. Til syvende og sist, når disse tegnene er nødvendige i programmet, vil de bli hentet fra bufferen, ikke direkte fra datakilden (tastatur, fil, etc.). Dette sparer mye ressurser. For å forstå hvordan dette fungerer, se for deg en kurer i et stort selskap. Kureren sitter på et kontor og venter på at noen skal bringe pakker for levering. Hver gang han mottar en ny pakke, kan han umiddelbart gå på veien. Men det kan bli mange pakker i løpet av dagen. Han måtte foreta mange turer mellom kontoret og leveringsadressene. I stedet setter kureren en boks på kontoret sitt. Alle legger pakkene sine i esken. Nå kan budet rolig ta boksen og flytte fra adresse til adresse. Dette sparer mye tid, fordi han ikke trenger å gå tilbake til kontoret hver gang. I dette eksemplet er boksen bare en buffer, og kontoret er en datakilde. Det er mye lettere for budet å ta pakker fra en enkelt boks når de skal levere enn å gå tilbake til kontoret hver gang. Han sparer bensin også. På samme måte er det i et program mye mindre ressurskrevende å ta data fra en buffer enn å referere til datakilden hver gang. Som et resultat,BufferedReader+ InputStreamReaderer raskere enn InputStreamReaderalene . Vi har vurdert ytelse. Hva med bekvemmelighet? Den største fordelen er at den Bufferedreaderkan lese data ikke bare ett tegn om gangen (selv om det kan gjøre dette med read()metoden sin), men også hele linjer om gangen! Dette gjøres ved hjelp av readLine()metoden;

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);
   }
}
Konsollutgang: CodeGym er det beste nettstedet for å lære Java! Vi leser denne linjen fra tastaturet: CodeGym er den beste nettsiden for å lære Java! Dette er spesielt nyttig når du leser store mengder data. Det er fortsatt mulig å lese en eller to linjer med tekst tegn for tegn. Men å lese i "Krig og fred" en bokstav om gangen ville vært noe problematisk :)

Mer lesing:

Kommentarer
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION