Programavimas

„Java 101“: Standartinio įvesties / išvesties ypatybės

Anksčiau „Java 101“ straipsniuose nurodžiau peradresavimo, standartinio įvesties įrenginio ir standartinio išvesties įrenginio sąvokas. Norint parodyti įvestus duomenis, buvo pateikti keli pavyzdžiai System.in.read (). Paaiškėjo, kad System.in.read () įveda duomenis iš standartinio įvesties įrenginio. Norėdami parodyti duomenų pateikimą, buvo pateikti pavyzdžiai System.out.print () ir System.out.println (). Priešingai nei System.in.read (), tie metodai - įvardytos vykdomojo kodo sekos (kurios bus nagrinėjamos kito mėnesio straipsnyje) - išsiųskite savo išvestį į standartinį išvesties įrenginį. Norite sužinoti daugiau apie standartines įvesties / išvesties koncepcijas? Skaityk!

Standartinis įvestis / išvestis yra standartizuotas įvesties / išvesties mechanizmas, kilęs iš „Unix“ operacinės sistemos. Nors šis mechanizmas dažniausiai naudojamas su senesnėmis ne GUI operacinėmis sistemomis, standartinis įvestis / išvestis vis dar vaidina svarbų vaidmenį šiuolaikinėse GUI (grafinės vartotojo sąsajos) operacinėse sistemose, kur žmonės ją naudoja derindami netinkamai veikiančias programas ir mokydami įvesties / išvesties įeinant. lygio programavimo kursai.

Kaip jūs tikriausiai atspėjote, standartinis įvesties / išvesties įtaisai naudojami duomenims įvesti ir pateikti. Šie prietaisai apima standartinę įvestį, standartinę išvestį ir standartinę paklaidą.

Standartinis įvestis

standartinis įvesties įrenginys yra ta operacinės sistemos dalis, kuri kontroliuoja, iš kur programa gauna savo indėlį. Pagal numatytuosius nustatymus standartinis įvesties įrenginys nuskaito tą įvestį iš įrenginio tvarkyklės, prijungtos prie klaviatūros. Tačiau galite peradresuoti, arba perjunkite prie įrenginio tvarkyklės, prijungtos prie failo, įvesties šaltinį, kad įvestis atrodytų „stebuklingai“ iš failo, o ne iš klaviatūros.

Programa įves savo duomenis iš standartinio įvesties įrenginio paskambindama „Java“ System.in.read () metodas. Peržiūrėkite SDK dokumentaciją ir rasite klasę, vadinamą Sistema. Toje klasėje yra kintamasis, vadinamas į objektas, sukurtas iš „InputStream“. Laikotarpio personažas po Sistema teigia, kad į priklauso Sistemair laikotarpio simbolis po į teigia, kad skaityti () priklauso į. Kitaip tariant, skaityti () yra metodas, priklausantis objektui, vadinamam į, kuri savo ruožtu priklauso klasei, vadinama Sistema. (Kitą mėnesį plačiau aptarsiu klases, objektus ir „priklausymą“.)

System.in.read () nepriima jokių argumentų ir pateikia sveiką skaičių, kuris privertė kai kuriuos tuo patikėti System.in.read () pateikia vartotojo įvestus sveikųjų skaičių skaičius. Paaiškinti, System.in.read () arba grąžina rakto 7 bitų ASCII kodą (jei standartinis įvesties įrenginys nustatytas į klaviatūrą), arba 8 bitų baitą iš failo (jei standartinis įvesties įrenginys buvo nukreiptas iš klaviatūros į failą). Bet kuriuo atveju, System.in.read () konvertuoja kodą į 32 bitų sveikąjį skaičių ir grąžina rezultatą.

Tarkime, kad standartinis įvesties įrenginys nustatytas į klaviatūrą. Toliau aprašoma, kas vyksta naudojant „Windows“: Kai įvedate raktą „Windows“ valdomoje klaviatūroje, operacinė sistema saugo to rakto 7 bitų ASCII kodą vidiniame rakto buferyje. Šis raktinis buferis talpina iki maždaug 16 ASCII kodų ir yra organizuojamas kaip „pirmojo į pirmą / iš pirmąjį žiedinės eilės duomenų struktūra“. System.in.read () nuskaito ASCII kodą iš rakto buferio galvos ir pašalina tą kodą iš rakto buferio. Tada tas 7 bitų ASCII kodas konvertuojamas į tarpt - pagal System.in.read () iš anksto pridedant 25 nulinius bitus kodui - ir grįžta pas metodo skambintoją. Sekundė System.in.read () metodo iškvietimas gauna kitą ASCII kodą, kuris dabar yra rakto buferio galvutėje ir pan.

Tarkime, kad rakto buferyje nėra ASCII kodų. Kas atsitinka? System.in.read () laukia, kol vartotojas suras klavišus ir paspaus terminatorių. Pagal "Windows" tas terminatorius yra Įveskite Raktas. Spaudimas Įveskite priverčia „Windows“ raktų buferyje saugoti vežimo grąžinimo kodą (ASCII 13), po kurio seka naujos eilutės kodas (ASCII 10). Todėl rakto buferyje gali būti keli ASCII kodai, po kurių eina vežimo grįžimas ir naujos eilutės simbolis. Pirmasis iš šių kodų grįžta iš System.in.read (). Patikrinkite tą veiklą įvesdami, sudarydami ir paleisdami Aidas taikymas; jo šaltinio kodas rodomas 1 sąraše.

Sąrašas 1. Echo.java

// Echo.java klasė Echo {public static void main (String [] args) meta java.io.IOException {int ch; System.out.print ("Įveskite tekstą:"); while ((ch = Sistema.skaityta ())! = '\ n') Sistema.out.print ((char) ch); }} 

Aidas atlieka šiuos veiksmus:

  1. Skambina System.out.print () metodas, kuriam reikalingas a Stygos argumentą, kad būtų išvestas raginimas
  2. Skambučiai System.in.read () įvesti ASCII kodus iš standartinio įvesties įrenginio kaip 32 bitų sveikus skaičius
  3. Konvertuoja tuos 32 bitų sveikus skaičius į 16 bitų „Unicode“ simbolius (char) mesti
  4. Skambina System.out.print () metodas, kuriam reikalingas a char argumentą, norint pakartoti tuos „Unicode“ simbolius prie standartinio išvesties įrenginio

Paskutiniai trys ankstesnių keturių žingsnių veiksmai vyksta tam tikru momentu ir tęsiasi tol, kol bus perskaitytas naujos eilutės simbolis. Bėgti Aidas kad jis įvestų iš klaviatūros ir išvestų į ekraną, išleiskite šią komandinę eilutę: java Echo.

Nors System.in.read () niekada nemeta išimties (šio termino apibrėžimą žr. šio straipsnio žodžių skaičiavimo temoje), kai standartinis įvesties įrenginys nustatytas į klaviatūrą, jis gali sukelti išimtį, kai peradresuojate standartinį įvesties įrenginį iš klaviatūros į failą. Pavyzdžiui, tarkime, kad peradresuojate standartinį įvesties įrenginį į failą ir System.in.read () skaito turinį iš bylos. Dabar tarkime, kad failas yra diskelyje ir vartotojas išstumia diską skaitymo operacijos metu. Kai bus išstumta, System.in.read () išmeta išimtį, informuodamas programą, kad ji negali perskaityti failo. Tai pateikia priežastį, kodėl reikia pridėti meta java.io.IOException straipsnis pagrindinis () metodo antraštė. (Išnagrinėsite išimtis, išimčių išmetimą ir susijusias sąvokas būsimame straipsnyje.)

Kaip peradresuoti standartinį įvesties įrenginį, kad įvestis būtų iš failo? Atsakymas yra įvesti mažiau nei ženklą, <, komandinėje eilutėje ir sekite tą simbolį su failo pavadinimu. Norėdami pamatyti, kaip tai veikia, išleiskite šią komandinę eilutę: java Echo <>. Komandinė eilutė nukreipia standartinį įvesties įrenginį į vadinamą failą Echo.java. Kada Aidas eina, nes kiekviena eilutė baigiasi naujos eilutės simboliu, tik pirmoje eilutėje Echo.java pasirodys ekrane.

Tarkime, kad jums reikia pagalbinės programos, kuri nuskaito visą failą ir ekrane rodo failo turinį, nukopijuoja turinį į kitą failą arba nukopijuoja jį į spausdintuvą. Deja, Aidas programa atlieka tik tą užduotį, kol ji susiduria su pirmuoju naujos eilutės simboliu. Ką tu darai? Atsakymas į problemą slypi Tipas taikymas. 2 sąraše pateikiamas šaltinio kodas:

Sąrašas 2. Tipas.java

// Type.java klasė Type {public static void main (String [] args) meta java.io.IOException {int ch; o ((ch = Sistema.skaityta ())! = -1) Sistema.out.print ((char) ch); }} 

Tipas primena Aidas, tačiau nėra skubos, o „while loop“ bando -1 (kuris nurodo failo pabaigą) vietoj \ n (kuris rodo eilutės pabaigą). Bėgti Tipas, išleiskite šią komandinę eilutę: java Tipas <>. Turinys Tipas.java - ar koks failas bus nurodytas - bus rodomas. Kaip eksperimentą pabandykite nurodyti java Tipas. Kaip manote, kas nutiks? (Patarimas: ši programa panaši į Aidas bet nesibaigia, kol nepaspaudi „Ctrl“ + C.)

Anksčiau minėjau, kad kai kurie programuotojai tai klaidingai mano System.in.read () grąžina vartotojo įvestą numerį. Kaip ką tik matėte, taip nėra. Bet ką turite daryti, jei norite naudoti System.in.read () gauti numerį? Pažvelkite į Paversti programa, kurios šaltinio kodas pateiktas 3 sąraše.

Sąrašas 3. Convert.java

// Convert.java klasė Konvertuoti {public static void main (String [] args) meta java.io.IOException {System.out.print ("Įveskite skaičių:"); int skaičius = 0; int ch; while ((ch = System.in.read ())! = '\ n') if (ch> = '0' && ch <= '9') {skaičius * = 10; num + = ch - '0'; } dar pertrauka; System.out.println ("num =" + num); System.out.println ("num squared =" + num * num); }} 

3 sąrašas Paversti programa ragina vartotoją įvesti numerį (per System.out.print ("Įveskite numerį:");). Jis nuskaito šiuos skaičius po vieną ir paverčia kiekvieno skaitmens skaitmeninį kodą dvejetainiu skaičiumi, kuris pridedamas prie kintamojo, vadinamo skaičius. Galiausiai, skambučiai System.out.println () išvesties vertę viduje skaičius ir tos vertės kvadratas iki standartinio išvesties įrenginio.

Paversti demonstruoja laikui bėgant taikytą metodą, kai naudojamas ciklo ciklas, norint patikrinti skaitmenį, iš anksto dauginant kintamąjį 10 (kad atsirastų vietos gaunamam skaitmeniui), paverčiant skaitmenį dvejetainiu jo atitikmeniu ir pridedant tą dvejetainį atitikmenį kintamajam. Tačiau ši technika nėra tinkama technika, kurią reikia naudoti, jei rašote programą, skirtą dislokuoti skirtingose ​​šalyse, nes kai kuriose šalyse naudojami kiti nei 0–9 skaitmenys, pavyzdžiui, tamilų skaitmenys. Kad programa veiktų su kitais skaitmenimis, turite išplėsti „if“ sakinį, kad patikrintumėte tuos skaitmenis ir pakeistumėte ch - „0“ išraiška. Laimei, „Java“ supaprastina šią užduotį pateikdama Charakteris klasė, kurią nagrinėsite būsimame straipsnyje.

Standartinė išvestis

standartinis išvesties įrenginys yra ta operacinės sistemos dalis, kuri kontroliuoja, kur programa siunčia savo išvestį. Pagal numatytuosius nustatymus standartinis išvesties įrenginys siunčia išvestį į įrenginio tvarkyklę, prijungtą prie ekrano. Tačiau išvesties paskirtį galima nukreipti į įrenginio tvarkyklę, prijungtą prie failo ar spausdintuvo, todėl ta pati programa ekrane rodo savo išvadas, išsaugo jas faile arba pateikia rezultatų spausdintą kopiją.

Standartinę išvestį pasiekiate paskambinę „Java“ System.out.print () ir System.out.println () metodai. Išskyrus tai, kad spausdinti () metodai po duomenų neišleidžia naujo eilutės simbolio, abi metodų grupės yra lygiavertės. Yra metodai, skirti išgauti Būlio, simbolių, simbolių masyvo, dvigubo tikslumo slankiojo kablelio, slankiojo kablelio, sveiko skaičiaus, ilgojo sveiko skaičiaus, eilutės ir objekto reikšmes. Norint parodyti šiuos metodus, 4 sąraše pateikiamas šaltinio kodas Spausdinti taikymas.

Sąrašas 4. Print.java

// Print.java klasė Spausdinti {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); dvigubas d = 3,5; System.out.println (d); plūdė f = -9,3f; System.out.println (f); int i = 'X'; System.out.println (i); ilgas l = 9000000; System.out.println (l); Eilutė s = "abc"; System.out.println (s); System.out.println (naujas spausdinimas ()); }} 

4 sąrašas tikriausiai sukėlė jums keletą klausimų. Pirma, kas yra visa tai System.out. verslas, veikiantis priešais println ()? Vėlgi kreipkitės į Sistema klasę SDK dokumentuose. Klasėje yra kintamasis, vadinamas išėjo - objektas, sukurtas iš klasės, vadinamos „PrintStream“. Laikotarpio personažas po Sistema rodo tai išėjo priklauso Sistema. Laikotarpio personažas po išėjo teigia, kad println () priklauso išėjo. Kitaip tariant, println () yra metodas, priklausantis objektui, vadinamam išėjo, kuri savo ruožtu priklauso klasei, vadinama Sistema.

Antras klausimas, kurį galite sau užduoti, yra susijęs println () argumentų duomenų tipai: kaip tai įmanoma println () metodas, kurį reikia iškviesti su skirtingų tipų argumentų duomenimis? Atsakymas: nes yra keli println () metodai „PrintStream“ klasė. Vykdymo metu JVM žino, kuris println () metodas skambinti, nagrinėdamas metodo iškvietimo argumentų skaičių ir jų duomenų tipus. (Kelių metodų deklaravimas tuo pačiu pavadinimu, bet skirtingu argumentų skaičiumi ir argumentų duomenų tipais yra žinomas kaip metodo perkrovimas. Aš aptarsiu šią koncepciją kitą mėnesį.)

Galiausiai jums gali būti įdomu System.out.println (naujas spausdinimas ());. Šis metodo skambutis iliustruoja println () metodas, kuriam reikalingas Objektas argumentas. Pirma, kūrimo operatorius naujas sukuria objektą iš Spausdinti klasę ir grąžina nuorodą į tą objektą, kuris dar žinomas kaip adresas. Galiausiai šis adresas kaip argumentas perduodamas println () metodas, kuriam reikalingas Objektas argumentas. Metodas paverčia objekto turinį į eilutę ir išleidžia tą eilutę. Pagal numatytuosius nustatymus eilutę sudaro objekto klasės pavadinimas, po kurio yra @ (at) simbolis, po kurio nurodomas šešioliktainis formatas suformuotas sveikas skaičius, nurodantis objekto maišos kodą. (Būsimame straipsnyje pateiksiu maišos kodus ir objektų pavertimą eilutėmis.)

Sudaryti Spausdinti.java ir paleiskite programą išleisdami šią komandinę eilutę: java Print. Turėtumėte pamatyti devynias išvesties eilutes. Nukreipkite tą išvestį į out.dat failą išleisdami šią komandinę eilutę: java Spausdinti> out.dat. Dabar galite peržiūrėti failo turinį.

Didesnis už ženklą, >, rodo standartinį išvesties peradresavimą. Kai norite peradresuoti standartinį išvesties įrenginį iš ekrano į failą ar spausdintuvą, komandinėje eilutėje nurodykite tą simbolį ir failo ar spausdintuvo pavadinimą. Pavyzdžiui, peradresuoti Spausdintiišvestį į „Windows“ spausdintuvą išduodant šią komandinę eilutę: java Spausdinti> prn.