CodeGym /Java blog /Tilfældig /Læser fra tastaturet: "læsere"
John Squirrels
Niveau
San Francisco

Læser fra tastaturet: "læsere"

Udgivet i gruppen
Hej! Lektionerne og opgaverne på niveau 3 lærte dig, hvordan du viser ting på konsollen, og i den anden retning, hvordan du læser data fra tastaturet.
Læsning fra tastaturet: "læsere" - 1
Du har endda lært at bruge følgende komplekse konstruktion til at opnå dette:

BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
Men der er et spørgsmål, vi ikke har besvaret endnu.

Hvordan i alverden fungerer det her?

I virkeligheden er programmer sjældent helt uafhængige. De kommunikerer med andre programmer, systemer, internettet osv. Med "kommunikere" mener vi primært "udveksle data". Det vil sige, at de modtager nogle eksterne data og sender også interne programdata et sted hen. Eksempler på programmer, der udveksler data, florerer i hverdagen. For eksempel lader mange websteder dig logge ind med din Facebook- eller Twitter-konto i stedet for at registrere dig. I denne situation udveksler to programmer (f.eks. Twitter og den hjemmeside, du logger på) de nødvendige data. Det endelige resultat er, at du er logget ind. Ordet "stream"bruges til at beskrive processen med dataudveksling. Hvor kom dette navn fra? Efter din erfaring kan en "strøm" være mere forbundet med floder og end med programmering. Det er ikke tilfældigt :) En strøm er i bund og grund et stykke data i bevægelse. Med andre ord, i programmering er det ikke vand, der flyder - men derimod data i form af bytes og tegn. Vi kan modtage bits af data fra en datastrøm og derefter bruge dem. Igen vil vi bruge vand/flow-analogien: du kan øse vand fra en flod for at lave suppe, slukke ild eller vande dine blomster. Streams giver dig mulighed for at arbejde med enhver datakilde: om internettet, din computers filsystem eller noget andet - det gør ingen forskel. Streams er et universelt værktøj. De tillader et program at modtage data fra hvor som helst (input-strømme) og sende dem hvor som helst (outputstrømme). Deres opgave er den samme: at tage data fra ét sted og sende dem til et andet. Der er to typer strømme:
  1. Inputstrømme bruges til at modtage data
  2. Outputstrømme er til afsendelse af data.
I Java implementeres disse strømme af klasserne InputStreamog OutputStream. Men vandløbene kan kategoriseres på en anden måde. Ud over input- og outputstrømme taler vi også om bytestrømme og karakterstrømme . Betydningen her burde være klar nok: bytestrøm sender information som et sæt bytes, mens en tegnstrøm sender det som et sæt tegn. I denne lektion vil vi dvæle ved inputstrømme. Jeg sætter et link med information om output-streams i slutningen af ​​lektionen. Du kan læse den på egen hånd :) Tag nu et kig på denne kode:

BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
Da du gik gennem lektionerne, syntes du så ikke, at denne linje var ret skræmmende? :) Det vil ikke være tilfældet, når vi har undersøgt, hvordan det fungerer. Lad os rette tingene op. Vi starter til sidst. System.iner et InputStreamobjekt, en forekomst af den klasse, vi talte om tidligt. Det er en inputstrøm, der er knyttet til en systeminputenhed (tastaturet). Forresten, du er indirekte bekendt med denne stream. Når alt kommer til alt, bruger du ofte dens "kollega" — System.out! System.outer systemets outputstrøm . Den bruges til at udlæse data til konsollen via din yndlingsmetode System.out.println(), som du bruger konstant :) System.outer en stream til at sende data til konsollen, mensSystem.iner til at hente data fra tastaturet. Det hele er enkelt :) Hvad mere er, vi kan læse data fra tastaturet uden denne enorme konstruktion. Vi kan simpelthen 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, der lader dig læse data. Der er et problem: den læser bytes , ikke tegn . Det er kedeligt kun at bruge engelske bogstaver, så lad os prøve at læse det kinesiske tegn "魚" fra tastaturet (bare kopier dette bogstav herfra og indsæt det på konsollen ved hjælp af ctrl + v på pc eller Command + v Mac ) . Denne karakter betyder i øvrigt 'en fisk'. Konsoludgang: 233 173 154 10 Dette symbol og mange andre kinesere optager 3 bytes i computerens hukommelse (i modsætning til latinske bogstaver, som kun optager 1 byte). I dette tilfælde læses 4 bytes fra strømmen: de første tre repræsenterer tegnet "魚", og anden byte repræsenterer en ny linje (Enter). Derfor System.iner i sin usminkede form ikke en mulighed for os. Mennesker (med sjældne undtagelser!) ved ikke, hvordan man læser bytes. Men InputStreamReaderklassen kommer til undsætning! Lad os se, hvad det er for et dyr.

BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
Vi går videre System.intil InputStreamReader- objektet. Klassens navn siger det! Vi opretter et InputStreamReaderobjekt og sender det en inputstrøm, som det vil læse data fra. I dette tilfælde...

new InputStreamReader(System.in)
...vi fortæller det, "du vil læse data fra systeminputstrømmen (fra tastaturet)". Men dette er ikke dens eneste funktion! Den InputStreamReadermodtager ikke kun data fra streamen. Det konverterer også bytestrømme til karakterstrømme . Du behøver med andre ord ikke længere konvertere dataene fra "etler og nuller" til et "læsbart sprog". InputStreamreadergør alt for dig. Selvfølgelig InputStreamReaderer det ikke begrænset til at læse data fra konsollen. Den kan også læse 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 opretter vi en FileInputStream(en smag af InputStream), sender filstien ind og sender selve streamen til InputStreamReader. Nu vil den være i stand til at læse data fra filen (hvis en fil faktisk findes på stien, selvfølgelig). Vi bruger også InputStreamReaderklassens read()metode til at læse data (kilden til data er ligegyldig: konsollen, en fil eller et andet sted). Hvad er forskellen mellem System.in.read()og InputStreamReader.read()?\ Lad os igen prøve at læse tegnet "魚" med et InputStreamReader. Jeg minder dig om, hvad der faktisk blev læst af 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);
       }
   }
}
Konsol output: 39770 10 Forskellen er umiddelbart tydelig. Den sidste byte (der repræsenterer den nye linje) forbliver uændret (tallet 10), men tegnet "魚" blev konverteret til en enkelt kode "39770". Dette er, hvad det vil sige at læse karakterer! Hvis du ikke tror på, at 39770 repræsenterer bogstavet "魚", er det nemt at overbevise dig selv :)
import java.io.IOException;

public class Main {

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

       char x = 39770;
       System.out.println(x);
   }
}
Konsoludgang: Men hvis InputStreamReaderdet er så fantastisk, hvorfor har vi så også brug for BufferedReader? InputStreamReaderved, hvordan man læser data og konverterer bytes til tegn. Hvad mere kan vi forlange? Hvorfor en anden læser? :/ Svaret er meget enkelt: for større ydeevne og bekvemmelighed . Lad os starte med ydeevne. Når BufferedReaderden læser data, bruger den et særligt område kaldet en buffer, hvor den "lagrer" de tegn, den læser. I sidste ende, når disse tegn er nødvendige i programmet, vil de blive taget fra bufferen, ikke direkte fra datakilden (tastatur, fil osv.). Dette sparer mange ressourcer. For at forstå, hvordan dette fungerer, skal du forestille dig en kurer i et stort firma. Kureren sidder på et kontor og venter på, at nogen bringer pakker til levering. Hver gang han modtager en ny pakke, kan han straks komme på vej. Men der kan være mange pakker i løbet af dagen. Han skulle foretage en masse ture mellem kontoret og leveringsadresserne. I stedet sætter kureren en kasse på sit kontor. Alle lægger deres pakker i kassen. Nu kan kureren roligt tage kassen og flytte fra adresse til adresse. Det sparer meget tid, fordi han ikke skal tilbage på kontoret hver gang. I dette eksempel er boksen kun en buffer, og kontoret er en datakilde. Det er meget nemmere for kureren at tage pakker fra en enkelt kasse, når de skal levere end at gå tilbage til kontoret hver gang. Han vil også spare benzin. På samme måde er det i et program meget mindre ressourcekrævende at tage data fra en buffer end at referere til datakilden hver gang. Som resultat,BufferedReader+ InputStreamReaderer hurtigere end InputStreamReaderalene . Vi har overvejet ydeevne. Hvad med bekvemmelighed? Den største fordel er, at Bufferedreaderkan læse data ikke kun ét tegn ad gangen (selvom det kan gøre dette med sin read()metode), men også hele linjer ad gangen! Dette gøres ved hjælp af 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);
   }
}
Konsoloutput: CodeGym er den bedste hjemmeside til at lære Java! Vi læser denne linje fra tastaturet: CodeGym er den bedste hjemmeside til at lære Java! Dette er især nyttigt, når du læser store mængder data. Det er stadig muligt at læse en eller to tekstlinjer tegn for tegn. Men at læse i "Krig og Fred" et bogstav ad gangen ville være noget problematisk :)

Mere læsning:

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