1. Mga stream ng data
Bihirang magkaroon ng isang programa bilang isang isla sa sarili nito. Karaniwang nakikipag-ugnayan ang mga programa sa "labas na mundo". Ito ay maaaring mangyari sa pamamagitan ng pagbabasa ng data mula sa keyboard, pagpapadala ng mga mensahe, pag-download ng mga pahina mula sa Internet, o, kabaligtaran, pag-upload ng mga file sa isang malayong server.
Maaari tayong sumangguni sa lahat ng mga pag-uugaling ito sa isang salita: pagpapalitan ng data sa pagitan ng programa at sa labas ng mundo. Teka, hindi lang iyon isang salita.
Siyempre, ang palitan ng data mismo ay maaaring nahahati sa dalawang bahagi: pagtanggap ng data at pagpapadala ng data. Halimbawa, nagbasa ka ng data mula sa keyboard gamit ang isang Scanner
bagay — ito ay tumatanggap ng data. At nagpapakita ka ng data sa screen gamit ang isang System.out.println()
command — ito ay nagpapadala ng data.
Sa programming, ang terminong "stream" ay ginagamit upang ilarawan ang pagpapalitan ng data. Saan nagmula ang katagang iyon?
Sa totoong buhay, maaari kang magkaroon ng isang stream ng tubig o isang stream ng kamalayan. Sa programming, mayroon kaming mga stream ng data .
Ang mga stream ay isang maraming nalalaman na tool. Pinapayagan nila ang programa na makatanggap ng data mula sa kahit saan (mga stream ng input) at magpadala ng data kahit saan (mga stream ng output). Kaya, mayroong dalawang uri:
- Ang input stream ay para sa pagtanggap ng data
- Ang isang output stream ay para sa pagpapadala ng data
Upang gawing 'nasasalat' ang mga stream, sumulat ang mga tagalikha ng Java ng dalawang klase: InputStream
at OutputStream
.
Ang InputStream
klase ay may read()
paraan na hinahayaan kang magbasa ng data mula rito. At ang OutputStream
klase ay may isang write()
paraan na hinahayaan kang magsulat ng data dito. Mayroon din silang iba pang mga pamamaraan, ngunit higit pa sa na mamaya.
Mga byte stream
Anong uri ng data ang pinag-uusapan natin? Anong format ang kailangan nito? Sa madaling salita, anong mga uri ng data ang sinusuportahan ng mga klaseng ito?
Ito ay mga generic na klase, kaya sinusuportahan nila ang pinakakaraniwang uri ng data — ang byte
. Ang isang OutputStream
maaaring magsulat ng mga byte (at mga byte array), at ang isang InputStream
bagay ay maaaring magbasa ng mga byte (o mga byte array). Iyon lang — hindi nila sinusuportahan ang anumang iba pang uri ng data.
Bilang resulta, ang mga stream na ito ay tinatawag ding mga byte stream .
Ang isang tampok ng mga stream ay ang kanilang data ay maaari lamang basahin (o isulat) nang sunud-sunod. Hindi mo mababasa ang data mula sa gitna ng isang stream nang hindi binabasa ang lahat ng data na nauuna dito.
Ganito gumagana ang pagbabasa ng data mula sa keyboard sa buong Scanner
klase: magbasa ka ng data mula sa keyboard nang sunud-sunod, linya sa linya. Binabasa namin ang isang linya, pagkatapos ay ang susunod na linya, pagkatapos ay ang susunod na linya, at iba pa. Angkop, ang paraan para sa pagbabasa ng mga linya ay tinatawag na nextLine()
.
Ang pagsulat ng data sa isang OutputStream
ay nangyayari rin nang sunud-sunod. Ang isang magandang halimbawa nito ay ang console output. Mag-output ka ng isang linya, na sinusundan ng isa at isa pa. Ito ay sequential output. Hindi mo maaaring i-output ang unang linya, pagkatapos ay ang ikasampu, at pagkatapos ay ang pangalawa. Ang lahat ng data ay isinulat sa isang output stream nang sunud-sunod lamang.
Mga stream ng character
Nalaman mo kamakailan na ang mga string ay ang pangalawa sa pinakasikat na uri ng data, at totoo nga. Maraming impormasyon ang ipinapasa sa anyo ng mga character at buong string. Ang isang computer ay mahusay sa pagpapadala at pagtanggap ng lahat bilang mga byte, ngunit ang mga tao ay hindi gaanong perpekto.
Accounting para sa katotohanang ito, ang Java programmer ay sumulat ng dalawa pang klase: Reader
at Writer
. Ang Reader
klase ay kahalintulad ng InputStream
klase, ngunit read()
ang pamamaraan nito ay hindi nagbabasa ng mga byte, ngunit mga character ( char
). Ang Writer
klase ay tumutugma sa OutputStream
klase. At tulad ng Reader
klase, gumagana ito sa mga character ( char
), hindi bytes.
Kung ihahambing natin ang apat na klaseng ito, makukuha natin ang sumusunod na larawan:
Byte (byte) | Mga tauhan (char) | |
---|---|---|
Pagbasa ng datos |
|
|
Pagsusulat ng datos |
|
|
Praktikal na aplikasyon
Ang InputStream
, OutputStream
, Reader
at Writer
mga klase mismo ay hindi direktang ginagamit ng sinuman, dahil hindi sila nauugnay sa anumang mga konkretong bagay kung saan mababasa ang data (o kung saan maaaring isulat ang data). Ngunit ang apat na klase na ito ay may maraming descendant classes na maraming magagawa.
2. InputStream
klase
Ang InputStream
klase ay kawili-wili dahil ito ang parent class para sa daan-daang mga descendant na klase. Wala itong sariling data, ngunit mayroon itong mga pamamaraan na minana ng lahat ng mga nagmula nitong klase.
Sa pangkalahatan, bihira para sa mga stream object na mag-imbak ng data sa loob. Ang stream ay isang tool para sa pagbabasa/pagsusulat ng data, ngunit hindi sa storage. Sabi nga, may mga exception.
Mga pamamaraan ng InputStream
klase at lahat ng mga descendant na klase nito:
Paraan | Paglalarawan |
---|---|
|
Nagbabasa ng isang byte mula sa stream |
|
Nagbabasa ng hanay ng mga byte mula sa stream |
|
Binabasa ang lahat ng mga byte mula sa stream |
|
Nilalaktawan ang n mga byte sa stream (binabasa at itinatapon ang mga ito) |
|
Sinusuri kung ilang byte ang natitira sa stream |
|
Isinasara ang stream |
Sa madaling sabi, dumaan tayo sa mga pamamaraang ito:
read()
paraan
Ang read()
pamamaraan ay nagbabasa ng isang byte mula sa stream at ibinabalik ito. Maaaring nalilito ka sa int
uri ng pagbabalik. Ang uri na ito ay pinili dahil int
ito ang karaniwang uri ng integer. Ang unang tatlong byte ng int
ay magiging zero.
read(byte[] buffer)
paraan
Ito ang pangalawang variant ng read()
pamamaraan. Hinahayaan ka nitong basahin ang isang byte array mula sa isang InputStream
sabay-sabay. Ang array na mag-iimbak ng mga byte ay dapat na maipasa bilang argumento. Ang pamamaraan ay nagbabalik ng isang numero — ang bilang ng mga byte na aktwal na nabasa.
Sabihin nating mayroon kang 10 kilobyte buffer at nagbabasa ka ng data mula sa isang file gamit ang FileInputStream
klase. Kung ang file ay naglalaman lamang ng 2 kilobytes, ang lahat ng data ay ilo-load sa buffer array, at ibabalik ng pamamaraan ang numerong 2048 (2 kilobytes).
readAllBytes()
paraan
Isang napakahusay na pamamaraan. Binabasa lang nito ang lahat ng data mula sa InputStream
hanggang sa maubos ito at ibabalik ito bilang isang solong byte array. Ito ay napaka-madaling gamitin para sa pagbabasa ng maliliit na file. Ang mga malalaking file ay maaaring hindi pisikal na magkasya sa memorya, at ang pamamaraan ay magtapon ng isang pagbubukod.
skip(long n)
paraan
Ang pamamaraang ito ay nagpapahintulot sa iyo na laktawan ang unang n byte mula sa InputStream
bagay. Dahil ang data ay mahigpit na binabasa nang sunud-sunod, binabasa lang ng pamamaraang ito ang unang n byte mula sa stream at itinatapon ang mga ito.
Ibinabalik ang bilang ng mga byte na aktwal na nilaktawan (kung sakaling natapos ang stream bago n
nalaktawan ang mga byte).
int available()
paraan
Ibinabalik ng pamamaraan ang bilang ng mga byte na natitira pa sa stream
void close()
paraan
Isinasara ng close()
pamamaraan ang stream ng data at inilalabas ang mga panlabas na mapagkukunang nauugnay dito. Kapag naisara na ang isang stream, wala nang mababasang data mula rito.
Sumulat tayo ng isang halimbawang programa na kumukopya ng napakalaking file. Hindi namin magagamit ang readAllBytes()
paraan upang basahin ang buong file sa memorya. Halimbawa:
Code | Tandaan |
---|---|
|
InputStream para sa pagbabasa mula sa file OutputStream para sa write to file Buffer kung saan babasahin natin ang data Hangga't mayroong data sa stream Basahin ang data sa buffer Isulat ang data mula sa buffer hanggang sa pangalawang stream |
Sa halimbawang ito, gumamit kami ng dalawang klase: FileInputStream
ay isang descendant ng InputStream
para sa pagbabasa ng data mula sa isang file, at FileOutputStream
isang descendant ng OutputStream
para sa pagsulat ng data sa isang file. Pag-uusapan natin ang pangalawang klase mamaya.
Ang isa pang kawili-wiling punto dito ay ang real
variable. Kapag ang huling bloke ng data ay nabasa mula sa isang file, madali itong magkaroon ng mas mababa sa 64KB ng data. Alinsunod dito, kailangan nating i-output hindi ang buong buffer, ngunit bahagi lamang nito - ang mga unang real
byte. Ito mismo ang nangyayari sa write()
pamamaraan.
3. Reader
klase
Ang Reader
klase ay isang kumpletong analogue ng InputStream
klase. Ang tanging pagkakaiba ay gumagana ito sa mga character ( char
), hindi sa mga byte. Katulad ng InputStream
klase, ang Reader
klase ay hindi ginagamit saanman sa sarili nitong: ito ang parent class para sa daan-daang mga descendant na klase at tumutukoy sa mga karaniwang pamamaraan para sa lahat ng ito.
Mga pamamaraan ng Reader
klase (at lahat ng mga descendant na klase nito):
Paraan | Paglalarawan |
---|---|
|
Nagbabasa ng isa char mula sa stream |
|
Nagbabasa ng char array mula sa stream |
|
Lumalaktaw n chars sa stream (binabasa at itinatapon ang mga ito) |
|
Tinitingnan kung may natitira pa sa stream |
|
Isinasara ang stream |
Ang mga pamamaraan ay halos kapareho ng sa InputStream
klase, bagama't may kaunting pagkakaiba.
int read()
paraan
Binabasa ng paraang ito ang isa char
mula sa stream at ibinabalik ito. Lumalawak ang char
uri sa isang int
, ngunit ang unang dalawang byte ng resulta ay palaging zero.
int read(char[] buffer)
paraan
Ito ang pangalawang variant ng read()
pamamaraan. Hinahayaan ka nitong basahin ang isang char array mula sa isang Reader
sabay-sabay. Ang array na mag-iimbak ng mga character ay dapat maipasa bilang argumento. Ang pamamaraan ay nagbabalik ng isang numero — ang bilang ng mga character na aktwal na nabasa.
skip(long n)
paraan
Ang pamamaraang ito ay nagpapahintulot sa iyo na laktawan ang unang n mga character mula sa Reader
bagay. Gumagana ito nang eksakto kapareho ng katulad na pamamaraan ng InputStream
klase. Ibinabalik ang bilang ng mga character na aktwal na nilaktawan.
boolean ready()
paraan
Ibinabalik true
kung may mga hindi pa nababasang byte sa stream.
void close()
paraan
Isinasara ng close()
pamamaraan ang stream ng data at inilalabas ang mga panlabas na mapagkukunang nauugnay dito. Kapag naisara na ang isang stream, wala nang mababasang data mula rito.
Para sa paghahambing, sumulat tayo ng isang programa na kumukopya ng isang text file:
Code | Tandaan |
---|---|
|
Reader para sa pagbabasa mula sa isang file Writer para sa pagsulat sa isang file Buffer kung saan babasahin natin ang data Hangga't mayroong data sa stream Basahin ang data sa isang buffer Isulat ang data mula sa buffer hanggang sa pangalawang stream |
GO TO FULL VERSION