Ohjelmointi

Java 101: Tavallisen tulon / lähdön sisään- ja ulospäin

Ennen Java 101 Artikkeleissa viittasin uudelleenohjauksen, tavallisen syöttölaitteen ja vakiolähtölaitteen käsitteisiin. Tietojen syöttämisen osoittamiseksi useita esimerkkejä kutsuttiin System.in.read (). Osoittautuu niin System.in.read () syöttää tietoja tavallisesta syöttölaitteesta. Tietojen tuottamiseksi esimerkkejä kutsutaan System.out.print () ja System.out.println (). Toisin kuin System.in.read (), nuo menetelmiä - suoritettavan koodin nimetyt sekvenssit (tutkitaan ensi kuun artikkelissa) - lähettävät tuotoksensa vakiolähtölaitteeseen. Haluatko tietää enemmän tavallisista I / O-käsitteistä? Jatka lukemista!

Vakio I / O on standardoitu syöttö / lähtömekanismi, joka on peräisin Unix-käyttöjärjestelmästä. Vaikka tätä mekanismia käytetään enimmäkseen vanhempien ei-GUI-käyttöjärjestelmien kanssa, tavallisilla I / O: lla on silti rooli nykyaikaisissa GUI (graafinen käyttöliittymä) -käyttöjärjestelmissä, joissa ihmiset käyttävät sitä virhetoimintahäiriöiden ohjelmien virheenkorjaamiseen ja tulojen / lähtöjen opettamiseen pääsyn tason ohjelmointikurssit.

Kuten olet todennäköisesti arvannut, tavallinen I / O käyttää laitteita tietojen syöttämiseen ja tulostamiseen. Nämä laitteet sisältävät vakiotulon, vakiolähdön ja vakiovirheen.

Vakiotulo

tavallinen syöttölaite on se käyttöjärjestelmän osa, joka hallitsee, mistä ohjelma vastaanottaa syötteensä. Oletusarvoisesti vakiolaite lukee syötteen näppäimistöön liitetystä laiteohjaimesta. Voit kuitenkin uudelleenohjaus, tai vaihda tiedostoon liitetyn laiteohjaimen tulolähde siten, että tulo näyttää olevan "maagisesti" peräisin tiedostosta - näppäimistön sijaan.

Ohjelma syöttää tietonsa tavallisesta syöttölaitteesta soittamalla Java: ille System.in.read () menetelmä. Etsi SDK: n dokumentaatiosta luokka nimeltä Järjestelmä. Tämä luokka sisältää muuttujan nimeltä sisään - kohde, joka on luotu luokan InputStream. Ajanjakson merkki Järjestelmä toteaa sen sisään kuuluu Järjestelmäja jakson merkki sen jälkeen sisään toteaa sen lukea() kuuluu sisään. Toisin sanoen, lukea() on menetelmä, joka kuuluu nimettyyn objektiin sisään, joka puolestaan ​​kuuluu nimettyyn luokkaan Järjestelmä. (Keskustelen lisää luokista, esineistä ja "kuulumisesta" ensi kuussa.)

System.in.read () ei ota argumentteja ja palauttaa kokonaisluvun, mikä on saanut jotkut uskomaan siihen System.in.read () palauttaa käyttäjän syöttämät kokonaisluvut. Selventää, System.in.read () joko palauttaa avaimen 7-bittisen ASCII-koodin (jos tavallinen syöttölaite on asetettu näppäimistölle) tai 8-bittisen tavun tiedostosta (jos tavallinen syöttölaite on ohjattu näppäimistöltä tiedostoon). Kummassakin tapauksessa, System.in.read () muuntaa koodin 32-bittiseksi kokonaisluvuksi ja palauttaa tuloksen.

Oletetaan, että tavallinen syöttölaite on asetettu näppäimistölle. Seuraava on kuvaus Windows-käyttöjärjestelmässä: Kun kirjoitat avaimen Windows-ohjatulle näppäimistölle, käyttöjärjestelmä tallentaa kyseisen avaimen 7-bittisen ASCII-koodin sisäiseen avaimen puskuriin. Tähän avainpuskuriin mahtuu noin 16 ASCII-koodia ja se on järjestetty ensimmäisenä sisään / ensimmäisenä ulos pyöreän jonon tietorakenteeseen. System.in.read () hakee ASCII-koodin avaimen puskurin päästä ja poistaa sen sitten avaimen puskurista. Se 7-bittinen ASCII-koodi muuntuu sitten int - kirjoittanut System.in.read () valmiiksi 25 nolla bittiä koodiin - ja palaa menetelmän soittajalle. Sekunti System.in.read () method-kutsu hakee seuraavan ASCII-koodin, joka on nyt avaimen puskurin kärjessä, ja niin edelleen.

Oletetaan, että avaimen puskurissa ei ole ASCII-koodeja. Mitä tapahtuu? System.in.read () odottaa, että käyttäjä kirjoittaa näppäimiä ja painaa päätintä. Windowsissa kyseinen terminaattori on Tulla sisään avain. Paina Tulla sisään aiheuttaa Windowsin tallentamaan kuljetuspalautuskoodin (ASCII 13) ja sen jälkeen uuden rivin koodin (ASCII 10) avainpuskuriin. Siksi avainpuskuri voi sisältää useita ASCII-koodeja, joita seuraa rivinvaihto ja uuden rivin merkki. Ensimmäinen näistä koodeista palaa System.in.read (). Tarkista kyseinen toiminta avaamalla, kääntämällä ja suorittamalla Kaiku sovellus; sen lähdekoodi näkyy luettelossa 1.

Listaus 1. Echo.java

// Echo.java class Echo {public static void main (String [] args) heittää java.io.IOException {int ch; System.out.print ("Kirjoita tekstiä:"); while ((ch = System.in.read ())! = '\ n') System.out.print ((char) ch); }} 

Kaiku suorittaa seuraavat vaiheet:

  1. Soittaa System.out.print () menetelmä, joka vie a Merkkijono argumentti, kehotteen antamiseksi
  2. Puhelut System.in.read () syöttää ASCII-koodit vakiosyöttölaitteelta 32-bittisinä kokonaislukuina
  3. Muuntaa nämä 32-bittiset kokonaisluvut 16-bittisiksi Unicode-merkkeiksi (hiiltyä) heittää
  4. Soittaa System.out.print () menetelmä, joka vie a hiiltyä argumentti, kaikuttamaan nämä Unicode-merkit vakiolähtölaitteeseen

Viimeisten neljän vaiheen kolme viimeistä vaihetta tapahtuvat hetkessä ja jatkuvat, kunnes uusi rivi luetaan. Juosta Kaiku anna seuraava komentorivi niin, että se syöttää näppäimistöltä ja lähtee näytölle: java Echo.

Siitä huolimatta System.in.read () ei koskaan heitä poikkeusta (katso termin määritelmä tämän artikkelin sanalaskenta-aiheesta), kun tavallinen syöttölaite on asetettu näppäimistölle, se saattaa heittää poikkeuksen, kun ohjaat tavallisen syöttölaitteen uudelleen näppäimistöltä tiedosto. Oletetaan esimerkiksi, että ohjaat vakiosyöttölaitteen tiedostoon ja System.in.read () lukee sisällön tiedostosta. Oletetaan nyt, että tiedosto sijaitsee levykkeellä ja käyttäjä poistaa levyn lukutoiminnon aikana. Kun työntö tapahtuu, System.in.read () heittää poikkeuksen ja ilmoittaa ohjelmalle, että se ei voi lukea tiedostoa. Se antaa syyn liittää heittää java.io.IOException lauseke main () method-otsikko. (Tutkit poikkeuksia, heittää poikkeuksia ja niihin liittyviä käsitteitä tulevasta artikkelista.)

Kuinka ohjaat vakiosyöttölaitteen siten, että syöte tulee tiedostosta? Vastaus on ottaa käyttöön vähemmän kuin merkki, <, komentorivillä ja seuraa kyseistä symbolia tiedostonimellä. Jos haluat nähdä, miten se toimii, anna seuraava komentorivi: java Echo <>. Komentorivi ohjaa vakiosyöttölaitteen tiedostoon nimeltä Kaiku.java. Kun Kaiku suoritetaan, koska jokainen rivi päättyy uuteen riviin, vain tekstin ensimmäinen rivi Kaiku.java tulee näyttöön.

Oletetaan, että tarvitset apuohjelmaa, joka lukee koko tiedoston ja joko näyttää tiedoston sisällön näytöllä, kopioi sisällön toiseen tiedostoon tai kopioi sisällön tulostimeen. Valitettavasti Kaiku Ohjelma suorittaa kyseisen tehtävän vain, kunnes se kohtaa ensimmäisen uuden rivin merkin. Mitä sinä teet? Vastaus ongelmaan on Tyyppi sovellus. Listaus 2 tarjoaa lähdekoodin:

Listaus 2. Kirjoita.java

// Type.java class Type {public static void main (String [] args) heittää java.io.IOException {int ch; kun ((ch = Järjestelmäluettelossa ())! = -1) Järjestelmän.ulostulostus ((char) k); }} 

Tyyppi muistuttaa Kaikuei kuitenkaan ole nopeaa, ja while-silmukka testaa -1 (mikä tarkoittaa tiedoston loppua) eikä \ n (mikä tarkoittaa rivin loppua). Juosta Tyyppi, anna seuraava komentorivi: java-tyyppi <>. Sisältö Kirjoita. Java - tai mikä tahansa tiedosto on määritetty - tulee näkyviin. Kokeile kokeilla määrittää java-tyyppi. Mitä luulet tapahtuvan? (Vihje: tämä ohjelma muistuttaa Kaiku mutta loppuu vasta, kun painat Ctrl + C.)

Aikaisemmin mainitsin, että jotkut ohjelmoijat ajattelevat sitä virheellisesti System.in.read () palauttaa käyttäjän kirjoittaman numeron. Kuten olet juuri nähnyt, niin ei ole. Mutta mitä sinun on tehtävä, jos haluat käyttää System.in.read () noutaa numero? Katsokaa Muuntaa sovellus, jonka lähdekoodi on esitetty luettelossa 3.

Listaus 3. Convert.java

// Convert.java class Muunna {public static void main (String [] args) heittää java.io.IOException {System.out.print ("Kirjoita numero:"); int numero = 0; int ch; while ((ch = System.in.read ())! = '\ n') if (ch> = '0' && ch <= '9') {numero * = 10; numero + = ch - '0'; } muu tauko; System.out.println ("num =" + num); System.out.println ("num squared =" + num * num); }} 

Luettelo 3: sta Muuntaa Ohjelma kehottaa käyttäjää syöttämään numeron (via System.out.print ("Anna numero:");). Se lukee nämä numerot - yksi kerrallaan - ja muuntaa jokaisen numeron numerokoodin binääriluvuksi, joka lisätään muuttujaan nimeltä numero. Lopuksi kutsuu System.out.println () tulostaa arvon sisällä numero ja kyseisen arvon neliö normaalilähtölaitteeseen.

Muuntaa havainnollistaa pitkään käytettyä tekniikkaa, jossa käytetään while-silmukkaa numeron testaamiseen, kertomalla muuttuja 10: llä (jotta tilaa saapuvalle numerolle), muunnettaessa luku binääriseksi ekvivalentiksi ja lisäämällä binäärinen vastine muuttujaan. Tämä tekniikka ei kuitenkaan ole hyvä tekniikka käytettäväksi, kun kirjoitat ohjelmaa käyttöönottoa varten eri maissa, koska joissakin maissa käytetään muita kuin 0–9 - kuten tamililaisia ​​- numeroita. Jotta ohjelma toimisi muiden numeroiden kanssa, sinun on laajennettava if-käsky testataksesi näitä numeroita ja muokkaamalla ch - '0' ilmaisu. Onneksi Java yksinkertaistaa tätä tehtävää tarjoamalla Merkki luokka, jota tutkit tulevassa artikkelissa.

Vakiolähtö

vakiolähtölaite on se käyttöjärjestelmän osa, joka ohjaa sitä, mihin ohjelma lähettää lähdön. Oletusarvoisesti vakiolähtölaite lähettää lähdön näyttöön liitetylle laiteohjaimelle. Lähtökohde voidaan kuitenkin ohjata tiedostoon tai tulostimeen liitettyyn laiteohjaimeen, mikä johtaa siihen, että sama ohjelma näyttää havainnot näytöllä, tallentaa ne tiedostoon tai toimittaa tulostettujen tulosten luettelon.

Normaalilähtö saavutetaan soittamalla Java-soittimille System.out.print () ja System.out.println () menetelmiä. Paitsi että Tulosta() menetelmät eivät tuota uuden rivin merkkiä tietojen jälkeen, nämä kaksi metodiryhmää vastaavat. Boolen, hahmo-, merkistö-, kaksoistarkkuuden liukuluku-, liukuluku-, kokonaisluku-, pitkä kokonaisluku-, merkkijono- ja objekti-arvojen tuottamiseksi on olemassa menetelmiä. Näiden menetelmien osoittamiseksi Listaus 4 esittää lähdekoodin Tulosta sovellus.

Listaus 4. Print.java

// Print.java-luokka Tulosta {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 (piirros); kaksinkertainen d = 3,5; System.out.println (d); kelluva f = -9,3f; System.out.println (f); int i = 'X'; System.out.println (i); pitkä l = 9000000; System.out.println (l); Merkkijono s = "abc"; System.out.println (s); System.out.println (uusi tulostus ()); }} 

Listaus 4 on todennäköisesti herättänyt joitain kysymyksiä sinulle. Ensinnäkin, mikä kaikki on System.out. liiketoiminnan tekeminen edessä println ()? Jälleen kerran viittaa Järjestelmä luokka SDK-dokumentaatiossa. Luokka sisältää muuttujan nimeltä ulos - esine, joka on luotu nimellisestä luokasta PrintStream. Ajanjakson merkki Järjestelmä ilmaisee sen ulos kuuluu Järjestelmä. Ajanjakson merkki ulos toteaa sen println () kuuluu ulos. Toisin sanoen, println () on menetelmä, joka kuuluu nimettyyn objektiin ulos, joka puolestaan ​​kuuluu nimettyyn luokkaan Järjestelmä.

Toinen kysymys, jonka saatat kysyä itseltäsi, liittyy println () argumenttitietotyypit: kuinka sama on mahdollista println () menetelmä kutsutaan erityyppisillä argumenttitiedoilla? Vastaus: koska niitä on useita println () menetelmät PrintStream luokassa. Ajon aikana JVM tietää mikä println () tapa kutsua tutkimalla method-call-argumenttien lukumäärä ja niiden tietotyypit. (Useiden menetelmien ilmoittaminen samalla nimellä, mutta erilaisten argumenttien ja argumenttitietojen lukumäärällä tunnetaan menetelmän ylikuormituksena. Keskustelen siitä käsitteestä ensi kuussa.)

Lopuksi saatat miettiä System.out.println (uusi tulostus ());. Tuo menetelmäpuhelu kuvaa println () menetelmä, joka vie Esine Perustelu. Ensinnäkin luontioperaattori Uusi luo objektin Tulosta luokka ja palauttaa viitteen - joka tunnetaan myös nimellä kyseisen objektin osoitteena. Lopuksi, tämä osoite kulkee argumenttina println () menetelmä, joka vie Esine Perustelu. Menetelmä muuntaa objektin sisällön merkkijonoksi ja tuottaa kyseisen merkkijonon. Merkkijono koostuu oletusarvoisesti objektiluokan nimestä ja sen jälkeen @ (at) -merkki, jota seuraa heksadesimaalimuodossa oleva kokonaisluku, joka edustaa objektin hash-koodia. (Esitän hashkoodit ja objektien muuntamisen merkkijonoiksi tulevassa artikkelissa.)

Koota Tulosta. Java ja aja ohjelma antamalla seuraava komentorivi: java Tulosta. Sinun pitäisi nähdä yhdeksän riviä lähtöä. Ohjaa tuotos osoitteeseen out.dat tiedosto julkaisemalla seuraava komentorivi: java Tulosta> out.dat. Voit nyt tarkastella tiedoston sisältöä.

Suurempi kuin merkki, >, osoittaa vakiolähdön uudelleenohjauksen. Aina kun haluat ohjata vakiolähtölaitteen näytöltä tiedostoon tai tulostimeen, määritä symboli, jota seuraa komentorivillä tiedosto tai tulostimen nimi. Esimerkiksi uudelleenohjaus Tulostalähdön Windows-tulostimeen antamalla seuraavan komentorivin: java Tulosta> prn.