Programmering

Java 101: Inn og ut av standard inngang / utgang

I tidligere Java 101 artikler, refererte jeg til begrepene omdirigering, standard inngangsenhet og standard utdataenhet. For å demonstrere inndata av data, flere eksempler kalt System.in.read (). Det viser seg at System.in.read () legger inn data fra standardinngangsenheten. For å demonstrere utdata, kalles eksempler System.out.print () og System.out.println (). I motsetning til System.in.read (), de metoder - navngitte sekvenser av kjørbar kode (skal utforskes i neste måneds artikkel) - sende utdataene til standardutdataenheten. Vil du vite mer om standard I / O-konsepter? Les videre!

Standard I / U er en standardisert inn / ut-mekanisme som stammer fra Unix-operativsystemet. Selv om denne mekanismen hovedsakelig brukes med eldre ikke-GUI-operativsystemer, spiller standard I / O fremdeles en rolle i moderne GUI-operativsystemer (grafisk brukergrensesnitt), der folk bruker den til å feilsøke feilfunksjoner og for å lære inn / ut i inngangs- programmeringskurs på nivå.

Som du sikkert har gjettet, bruker standard I / O enheter for å legge inn og ut data. Disse enhetene inkluderer standardinngang, standardutgang og standardfeil.

Standard inngang

De standard inngangsenhet er den delen av operativsystemet som styrer hvorfra et program mottar input. Som standard leser standardinngangsenheten den inngangen fra en enhetsdriver som er koblet til tastaturet. Du kan imidlertid omdirigere, eller bytt, inngangskilden til en enhetsdriver som er koblet til en fil, slik at inngangen ser ut til å komme "magisk" fra en fil - i stedet for tastaturet.

Et program legger inn dataene sine fra standardinngangsenheten ved å ringe Java-er System.in.read () metode. Se i SDK-dokumentasjonen, og du vil oppdage en klasse som heter System. Den klassen inneholder en variabel som heter i - et objekt opprettet fra en underklasse av InputStream. Perioden karakter etter System stater som i tilhører System, og periodekarakteren etter i stater som lese() tilhører i. Med andre ord, lese() er en metode som tilhører et objekt som heter i, som igjen tilhører en klasse som heter System. (Jeg vil diskutere mer om klasser, gjenstander og "tilhører" neste måned.)

System.in.read () tar ingen argumenter og returnerer et helt tall, noe som har fått noen til å tro det System.in.read () returnerer brukerinntatte heltall. Å avklare, System.in.read () enten returnerer en nøkkels 7-biters ASCII-kode (hvis standardinnmatingsenheten er satt til tastaturet) eller en 8-biters byte fra en fil (hvis standardinnmatingsenheten er omdirigert fra tastaturet til en fil). I begge tilfeller, System.in.read () konverterer koden til et 32-biters heltall og returnerer resultatet.

Anta at standard inngangsenhet er satt til tastaturet. Følgende er en beskrivelse av hva som skjer under Windows: Når du skriver en nøkkel på et Windows-kontrollert tastatur, lagrer operativsystemet nøkkelens 7-biters ASCII-kode i en intern nøkkelbuffer. Denne nøkkelbufferen har plass til omtrent 16 ASCII-koder og er organisert som en først inn / først ut sirkulær kødatastruktur. System.in.read () henter ASCII-koden fra hodet til nøkkelbufferen og fjerner den koden fra nøkkelbufferen. Den 7-biters ASCII-koden konverteres deretter til en int -- av System.in.read () forutgående 25 nullbiter til koden - og returnerer til metodens innringer. Et sekund System.in.read () method call henter neste ASCII-kode, som nå er i toppen av nøkkelbufferen, og så videre.

Anta at det ikke er noen ASCII-koder i nøkkelbufferen. Hva skjer? System.in.read () venter på at brukeren skal skrive inn taster og trykker på terminatoren. Under Windows er den terminatoren den Tast inn nøkkel. Pressing Tast inn fører til at Windows lagrer en vognreturkode (ASCII 13) etterfulgt av en ny linjekode (ASCII 10) i nøkkelbufferen. Derfor kan nøkkelbufferen inneholde flere ASCII-koder etterfulgt av en vognretur og et nytt linjetegn. Den første av disse kodene kommer tilbake fra System.in.read (). Sjekk ut den aktiviteten ved å taste inn, kompilere og kjøre Ekko applikasjon; kildekoden vises i liste 1.

Oppføring 1. Echo.java

// Echo.java klasse Echo {public static void main (String [] args) kaster java.io.IOException {int ch; System.out.print ("Skriv inn litt tekst:"); mens ((ch = System.in.read ())! = '\ n') System.out.print ((char) ch); }} 

Ekko fullfører følgende trinn:

  1. Ringer til System.out.print () metode, som tar en String argument, for å sende en melding
  2. Ringer System.in.read () å legge inn ASCII-koder fra standardinndataenheten som 32-biters heltall
  3. Konverterer disse 32-biters heltallene til 16-biters Unicode-tegn ved hjelp av (røye) rollebesetning
  4. Ringer til System.out.print () metode, som tar en røye argument, for å ekko disse Unicode-tegnene til standardutdataenheten

De tre siste trinnene i de fire foregående trinnene finner sted i en stund-løkke, og fortsetter til et nytt linjetegn blir lest. Å løpe Ekko slik at den inngår fra tastaturet og utgangene til skjermen, må du utstede følgende kommandolinje: java ekko.

Selv om System.in.read () kaster aldri et unntak (se ordtellingstemaet i denne artikkelen for en definisjon av det begrepet), når standard inngangsenhet er satt til tastaturet, kan det hende at det blir et unntak når du omdirigerer standard inngangsenhet fra tastaturet til et fil. Anta for eksempel at du viderekobler standard inndataenhet til en fil, og System.in.read () leser innhold fra filen. Anta nå at filen ligger på en diskett, og at brukeren skyver den ut under leseoperasjonen. Når utkastingen finner sted, System.in.read () kaster et unntak, og informerer programmet om at det ikke kan lese filen. Det gir grunn til å legge til kaster java.io.IOException klausul til hoved() metodehode. (Du vil utforske unntak, kaste unntak og relaterte konsepter i en fremtidig artikkel.)

Hvordan omdirigerer du standardinntastingsenheten slik at inndata kommer fra en fil? Svaret er å introdusere et mindre enn tegn, <, på kommandolinjen og følg symbolet med et filnavn. For å se hvordan det fungerer, send følgende kommandolinje: java ekko <>. Kommandolinjen omdirigerer standard inndataenhet til en fil som heter Ekko.java. Når Ekko kjører, fordi hver linje slutter med et nytt linje-tegn, bare den første teksten Ekko.java vises på skjermen.

Anta at du trenger et verktøy som leser en hel fil og enten viser filens innhold på skjermen, kopierer innholdet til en annen fil eller kopierer innholdet til en skriver. Dessverre, den Ekko programmet utfører bare oppgaven til den møter den første nye linjekarakteren. Hva gjør du? Svaret på problemet ligger i Type applikasjon. Oppføring 2 gir kildekoden:

Oppføring 2. Skriv.java

// Type.java-klasse Type {public static void main (String [] args) kaster java.io.IOException {int ch; mens ((ch = System.in.read ())! = -1) System.out.print ((char) ch); }} 

Type ligner EkkoDet er imidlertid ingen spørsmål, og mens loop tester mot -1 (som indikerer slutten på filen) i stedet for \ n (som indikerer slutten på linjen). Å løpe Type, utfør følgende kommandolinje: java Type <>. Innholdet i Skriv.java - eller hvilken fil som er spesifisert - vises. Prøv å spesifisere som et eksperiment java Type. Hva tror du vil skje? (Hint: dette programmet ligner Ekko men slutter ikke før du trykker Ctrl + C.)

Tidligere nevnte jeg at noen programmerere feilaktig tenker det System.in.read () returnerer et brukerinntastet nummer. Som du nettopp har sett, er det ikke tilfelle. Men hva må du gjøre hvis du vil bruke System.in.read () å hente et nummer? Ta en titt på Konvertere applikasjon, hvis kildekode er presentert i Listing 3.

Oppføring 3. Convert.java

// Convert.java class Convert {public static void main (String [] args) throw java.io.IOException {System.out.print ("Vennligst skriv inn et nummer:"); int num = 0; int ch; mens ((ch = System.in.read ())! = '\ n') hvis (ch> = '0' && ch <= '9') {num * = 10; num + = ch - '0'; } annet pause; System.out.println ("num =" + num); System.out.println ("num squared =" + num * num); }} 

Listing 3's Konvertere programmet ber brukeren om å skrive inn et nummer (via System.out.print ("Vennligst skriv inn et nummer:");). Den leser disse sifrene - en om gangen - og konverterer hvert siffer numeriske kode til et binært tall som legges til en variabel kalt num. Til slutt, kaller til System.out.println () mat ut verdien inni num og kvadratet av den verdien til standard utdataenhet.

Konvertere demonstrerer den tidskrevne teknikken med å bruke en while-loop for å teste for et siffer, for multiplisere en variabel med 10 (for å gi plass til det innkommende sifferet), konvertere et siffer til dets binære ekvivalent og legge til det binære ekvivalenten til variabelen. Imidlertid er den teknikken ikke en lydteknikk å bruke hvis du skriver et program for distribusjon i forskjellige land, da noen land bruker andre sifre enn 0 til 9 - for eksempel tamilske sifre. For å få programmet til å fungere med andre sifre, må du utvide if-setningen for å teste for disse sifrene og endre ch - '0' uttrykk. Heldigvis forenkler Java den oppgaven ved å tilby en Karakter klasse, som du vil utforske i en fremtidig artikkel.

Standard utgang

De standard utgangsenhet er den delen av operativsystemet som styrer hvor et program sender utdataene. Standardutgangsenheten sender som standard utdataene til en enhetsdriver som er koblet til skjermen. Imidlertid kan utgangsdestinasjonen omdirigeres til en enhetsdriver som er koblet til en fil eller skriver, noe som resulterer i at det samme programmet viser funnene på skjermen, lagrer dem i en fil eller gir en utskrift av resultatene.

Du oppnår standard produksjon ved å ringe Java System.out.print () og System.out.println () metoder. Bortsett fra det faktum at skrive ut() metoder sender ikke ut en ny linje etter dataene, de to metodegruppene er ekvivalente. Metoder eksisterer for å sende ut boolsk, tegn, tegnmatrise, dobbelt-presisjon flytende punkt, flytende punkt, heltall, langt heltall, streng og objektverdier. For å demonstrere disse metodene presenterer Listing 4 kildekoden til Skrive ut applikasjon.

Oppføring 4. Print.java

// Print.java klasse Skriv ut {public static void main (String [] args) {boolean b = true; System.out.println (b); char c = 'A'; System.out.println (c); char [] carray = {'A', 'B', 'C'}; System.out.println (carray); dobbel d = 3,5; System.out.println (d); flyte f = -9.3f; System.out.println (f); int i = 'X'; System.out.println (i); lang l = 9000000; System.out.println (l); Streng s = "abc"; System.out.println (s); System.out.println (ny utskrift ()); }} 

Oppføring 4 har sannsynligvis utløst noen spørsmål for deg. Først, hva er alt det? System.out. virksomhet gjør foran println ()? Igjen, referer til System klasse i SDK-dokumentasjonen. Klassen inneholder en variabel som heter ute - et objekt opprettet fra en klasse som heter PrintStream. Periodekarakteren etter System indikerer at ute tilhører System. Perioden karakter etter ute stater som println () tilhører ute. Med andre ord, println () er en metode som tilhører et objekt som heter ute, som igjen tilhører en klasse som heter System.

Det andre spørsmålet du kanskje stiller deg innebærer println () argumentdatatyper: hvordan er det mulig for det samme println () metode som skal kalles med forskjellige typer argumentdata? Svaret: fordi det er flere println () metoder i PrintStream klasse. Ved kjøretid vet JVM hvilken println () metode for å ringe ved å undersøke antall metodeanropsargumenter og deres datatyper. (Å erklære flere metoder med samme navn, men forskjellige antall argumenter og datatyper for argument er kjent som metodeoverbelastning. Jeg vil diskutere dette konseptet neste måned.)

Til slutt lurer du kanskje på System.out.println (ny utskrift ());. Denne metoden kalles println () metode, som tar en Gjenstand argument. Først etableringsoperatøren ny skaper et objekt fra Skrive ut klasse og returnerer en referanse til - også kjent som adressen til - det objektet. Til slutt passerer den adressen som et argument til println () metode, som tar en Gjenstand argument. Metoden konverterer objektets innhold til en streng og sender ut den strengen. Som standard består strengen av navnet på objektets klasse, etterfulgt av en @ (at) karakter, etterfulgt av et heksadesimalt formatert heltall som representerer objektets hashkode. (Jeg vil presentere hashkoder og konvertering av objekter til strenger i en kommende artikkel.)

Kompilere Skriv ut. Java og kjør programmet ved å utstede følgende kommandolinje: java utskrift. Du bør se ni linjer med utdata. Omdiriger utgangen til ut.dat filen ved å utstede følgende kommandolinje: java Skriv ut> out.dat. Du kan nå se innholdet i filen.

Større enn tegnet, >, indikerer standard utgående omdirigering. Når du vil omdirigere standardutdataenheten fra skjermen til en fil eller skriver, angir du symbolet etterfulgt av filen eller skrivernavnet på kommandolinjen. For eksempel omdirigering Skrive utsendes ut til en Windows-skriver ved å utstede følgende kommandolinje: java Skriv ut> prn.

$config[zx-auto] not found$config[zx-overlay] not found