1. กระแสข้อมูล
ไม่ค่อยมีโปรแกรมอยู่เป็นเกาะสำหรับตัวมันเอง โปรแกรมมักจะโต้ตอบกับ "โลกภายนอก" ซึ่งอาจเกิดขึ้นได้จากการอ่านข้อมูลจากแป้นพิมพ์ ส่งข้อความ ดาวน์โหลดเพจจากอินเทอร์เน็ต หรือในทางกลับกัน อัปโหลดไฟล์ไปยังเซิร์ฟเวอร์ระยะไกล
เราสามารถอ้างถึงพฤติกรรมทั้งหมดนี้ได้ในคำเดียว: การแลกเปลี่ยนข้อมูลระหว่างโปรแกรมกับโลกภายนอก รอนั่นไม่ใช่แค่คำเดียว
แน่นอนการแลกเปลี่ยนข้อมูลสามารถแบ่งออกเป็นสองส่วน: รับข้อมูลและส่งข้อมูล ตัวอย่างเช่น คุณอ่านข้อมูลจากแป้นพิมพ์โดยใช้Scannerวัตถุ — นี่คือการรับข้อมูล และคุณแสดงข้อมูลบนหน้าจอโดยใช้System.out.println()คำสั่ง — นี่คือการส่งข้อมูล
ในการเขียนโปรแกรม คำว่า "สตรีม" ใช้เพื่ออธิบายการแลกเปลี่ยนข้อมูล คำนั้นมาจากไหน?
ในชีวิตจริง คุณสามารถมีกระแสน้ำหรือกระแสแห่งสติได้ ในการ เขียนโปรแกรม เรามีdata streams
สตรีมเป็นเครื่องมืออเนกประสงค์ อนุญาตให้โปรแกรมรับข้อมูลจากทุกที่ (สตรีมอินพุต) และส่งข้อมูลได้ทุกที่ (สตรีมเอาต์พุต) ดังนั้นจึงมีสองประเภท:
- กระแสอินพุตใช้สำหรับรับข้อมูล
- กระแสข้อมูลออกสำหรับการส่งข้อมูล
ในการทำให้สตรีม ' จับต้องได้' ผู้สร้าง Java ได้เขียนสองคลาส: InputStreamและOutputStream
คลาสInputStreamมีread()เมธอดที่ให้คุณอ่านข้อมูลจากมันได้ และOutputStreamคลาสมีwrite()เมธอดที่ให้คุณเขียนข้อมูลลงไปได้ พวกเขามีวิธีอื่นเช่นกัน แต่จะเพิ่มเติมในภายหลัง
ไบต์สตรีม
เรากำลังพูดถึงข้อมูลประเภทใด ต้องใช้รูปแบบใด? กล่าวอีกนัยหนึ่ง คลาสเหล่านี้สนับสนุนประเภทข้อมูลใดบ้าง
คลาสเหล่านี้เป็นคลาสทั่วไป ดังนั้นจึงรองรับประเภทข้อมูลที่พบบ่อยที่สุด นั่นคือbyte. สามารถOutputStreamเขียนไบต์ (และอาร์เรย์ไบต์) และInputStreamวัตถุสามารถอ่านไบต์ (หรืออาร์เรย์ไบต์) แค่นั้นแหละ — ไม่รองรับประเภทข้อมูลอื่น ๆ
เป็นผลให้สตรีมเหล่านี้เรียกอีกอย่างว่าไบต์สตรีม
คุณลักษณะหนึ่งของสตรีมคือข้อมูลสามารถอ่าน (หรือเขียน) ตามลำดับเท่านั้น คุณไม่สามารถอ่านข้อมูลจากตรงกลางของสตรีมโดยไม่อ่านข้อมูลทั้งหมดที่มาก่อน
นี่คือวิธีการอ่านข้อมูลจากแป้นพิมพ์ผ่านScannerชั้นเรียน: คุณอ่านข้อมูลจากแป้นพิมพ์ตามลำดับ ทีละบรรทัด เราอ่านบรรทัดหนึ่ง บรรทัดถัดไป บรรทัดถัดไป และอื่นๆ วิธีการอ่านบรรทัดถูกเรียกnextLine()ว่า
การเขียนข้อมูลไปOutputStreamยัง an จะเกิดขึ้นตามลำดับ ตัวอย่างที่ดีคือเอาต์พุตคอนโซล คุณส่งออกบรรทัดตามด้วยอีกอันหนึ่ง นี่คือเอาต์พุตตามลำดับ คุณไม่สามารถแสดงผลบรรทัดแรก บรรทัดที่สิบ และบรรทัดที่สอง ข้อมูลทั้งหมดถูกเขียนไปยังเอาต์พุตสตรีมตามลำดับเท่านั้น
สตรีมตัวละคร
เมื่อเร็ว ๆ นี้คุณได้เรียนรู้ว่าสตริงเป็นประเภทข้อมูลที่ได้รับความนิยมเป็นอันดับสอง และแน่นอนว่าเป็นเช่นนั้น ข้อมูลจำนวนมากถูกส่งผ่านในรูปแบบของอักขระและสตริงทั้งหมด คอมพิวเตอร์เก่งในการส่งและรับทุกอย่างเป็นไบต์ แต่มนุษย์ไม่ได้สมบูรณ์แบบขนาดนั้น
จากข้อเท็จจริงนี้ โปรแกรมเมอร์ Java จึงเขียนคลาสเพิ่มเติมอีกสองคลาส: Readerและ Writerคลาส นั้นReaderคล้ายคลึงกับInputStreamคลาส แต่read()วิธีการอ่านไม่ใช่ไบต์ แต่เป็นอักขระ ( char) ชั้นWriterเรียนสอดคล้องกับOutputStreamชั้นเรียน และเช่นเดียวกับReaderคลาส ใช้ได้กับอักขระ ( char) ไม่ใช่ไบต์
หากเราเปรียบเทียบคลาสทั้งสี่นี้ เราจะได้ภาพต่อไปนี้:
| ไบต์ (ไบต์) | ตัวอักษร (ถ่าน) | |
|---|---|---|
| การอ่านข้อมูล |
|
|
| การเขียนข้อมูล |
|
|
การใช้งานจริง
คลาสInputStream, OutputStream, ReaderและWriterตัวเองไม่ได้ใช้โดยตรงโดยใครก็ตาม เนื่องจากไม่เกี่ยวข้องกับออบเจกต์คอนกรีตใดๆ ที่สามารถอ่านข้อมูลได้ (หรือข้อมูลที่สามารถเขียนลงไปได้) แต่ทั้งสี่คลาสนี้ก็มีคลาสสืบสกุลที่สามารถทำอะไรได้มากมาย
2. InputStreamชั้นเรียน
คลาส นี้InputStreamน่าสนใจเพราะเป็นคลาสหลักสำหรับคลาสลูกหลานหลายร้อยคลาส ไม่มีข้อมูลของตัวเอง แต่มีเมธอดที่คลาสที่ได้รับมาทั้งหมดสืบทอดมา
โดยทั่วไป เป็นเรื่องยากสำหรับสตรีมอ็อบเจ็กต์ที่จะจัดเก็บข้อมูลไว้ภายใน สตรีมเป็นเครื่องมือสำหรับการอ่าน/เขียนข้อมูล แต่ไม่ใช่การจัดเก็บ ที่กล่าวว่ามีข้อยกเว้น
เมธอดของInputStreamคลาสและคลาสที่สืบทอดมาทั้งหมด:
| วิธีการ | คำอธิบาย |
|---|---|
|
อ่านหนึ่งไบต์จากสตรีม |
|
อ่านอาร์เรย์ของไบต์จากสตรีม |
|
อ่านไบต์ทั้งหมดจากสตรีม |
|
ข้ามnไบต์ในสตรีม (อ่านและละทิ้ง) |
|
ตรวจสอบจำนวนไบต์ที่เหลืออยู่ในสตรีม |
|
ปิดสตรีม |
มาดูวิธีการเหล่านี้โดยสังเขป:
read()วิธี
เมธอดread()อ่านหนึ่งไบต์จากสตรีมและส่งกลับ คุณอาจสับสนกับintประเภทการคืนสินค้า เลือกประเภทนี้เนื่องจากintเป็นประเภทจำนวนเต็มมาตรฐาน สามไบต์แรกของค่าintจะเป็นศูนย์
read(byte[] buffer)วิธี
นี่คือตัวแปรที่สองของread()วิธีการ มันช่วยให้คุณอ่านอาร์เรย์ไบต์จากInputStreamทั้งหมดในครั้งเดียว อาร์เรย์ที่จะเก็บไบต์จะต้องผ่านเป็นอาร์กิวเมนต์ เมธอดส่งคืนตัวเลข — จำนวนไบต์ที่อ่านจริง
สมมติว่าคุณมีบัฟเฟอร์ 10 กิโลไบต์ และคุณกำลังอ่านข้อมูลจากไฟล์โดยใช้FileInputStreamคลาส หากไฟล์มีขนาดเพียง 2 กิโลไบต์ ข้อมูลทั้งหมดจะถูกโหลดลงในบัฟเฟอร์อาร์เรย์ และเมธอดจะคืนค่าเป็นตัวเลข 2048 (2 กิโลไบต์)
readAllBytes()วิธี
วิธีการที่ดีมาก มันแค่อ่านข้อมูลทั้งหมดจาก the InputStreamจนกว่าจะหมดและส่งกลับเป็นอาร์เรย์ไบต์เดียว สิ่งนี้มีประโยชน์มากสำหรับการอ่านไฟล์ขนาดเล็ก ไฟล์ขนาดใหญ่อาจไม่พอดีกับหน่วยความจำ และวิธีการจะส่งข้อยกเว้น
skip(long n)วิธี
วิธีนี้ช่วยให้คุณข้าม n ไบต์แรกจากInputStreamวัตถุได้ เนื่องจากข้อมูลถูกอ่านตามลำดับอย่างเคร่งครัด วิธีการนี้เพียงแค่อ่าน n ไบต์แรกจากสตรีมและละทิ้งข้อมูลเหล่านั้น
ส่งกลับจำนวนไบต์ที่ถูกข้ามจริง (ในกรณีที่สตรีมสิ้นสุดก่อนที่nจะข้ามไบต์)
int available()วิธี
เมธอดส่งคืนจำนวนไบต์ที่ยังคงอยู่ในสตรีม
void close()วิธี
เมธอดclose()จะปิดสตรีมข้อมูลและปล่อยทรัพยากรภายนอกที่เกี่ยวข้อง เมื่อสตรีมถูกปิด จะไม่สามารถอ่านข้อมูลได้อีก
ลองเขียนโปรแกรมตัวอย่างที่คัดลอกไฟล์ขนาดใหญ่มาก เราไม่สามารถใช้readAllBytes()วิธีอ่านไฟล์ทั้งหมดลงในหน่วยความจำได้ ตัวอย่าง:
| รหัส | บันทึก |
|---|---|
|
InputStreamสำหรับอ่านจากไฟล์OutputStreamสำหรับเขียนลงไฟล์บัฟเฟอร์ที่เราจะอ่านข้อมูล ตราบเท่าที่มีข้อมูลในสตรีม อ่านข้อมูลลงในบัฟเฟอร์ เขียนข้อมูลจากบัฟเฟอร์ไปยังสตรีมที่สอง |
ในตัวอย่างนี้ เราใช้สองคลาส: FileInputStreamเป็นคลาสสืบทอดของInputStreamสำหรับการอ่านข้อมูลจากไฟล์ และFileOutputStreamเป็นคลาสสืบทอดของOutputStreamสำหรับการเขียนข้อมูลไปยังไฟล์ เราจะพูดถึงชั้นสองในภายหลัง
อีกจุดที่น่าสนใจที่นี่คือrealตัวแปร เมื่อบล็อกข้อมูลสุดท้ายถูกอ่านจากไฟล์ ข้อมูลนั้นอาจมีน้อยกว่า 64KB ได้อย่างง่ายดาย ดังนั้น เราไม่จำเป็นต้องส่งออกบัฟเฟอร์ทั้งหมด แต่เพียงบางส่วนเท่านั้น - realไบต์ แรก นี่คือสิ่งที่เกิดขึ้นในwrite()วิธีการ นี้
3. Readerชั้นเรียน
คลาส นี้Readerเป็นอะนาล็อกที่สมบูรณ์ของInputStreamคลาส ข้อแตกต่างเพียงอย่างเดียวคือใช้ได้กับอักขระ ( char) ไม่ใช่กับไบต์ เช่นเดียวกับInputStreamคลาส คลาสReaderจะไม่ถูกใช้โดยลำพัง: เป็นคลาสพาเรนต์สำหรับคลาสที่สืบทอดมาหลายร้อยคลาส และกำหนดเมธอดทั่วไปสำหรับคลาสเหล่านั้นทั้งหมด
วิธีการของReaderคลาส (และคลาสที่สืบทอดมาทั้งหมด):
| วิธีการ | คำอธิบาย |
|---|---|
|
อ่านหนึ่งรายการcharจากสตรีม |
|
อ่านcharอาร์เรย์จากสตรีม |
|
ข้ามไปn charsในสตรีม (อ่านแล้วทิ้งไป) |
|
ตรวจสอบว่ายังมีสิ่งที่เหลืออยู่ในสตรีมหรือไม่ |
|
ปิดสตรีม |
เมธอดนั้นคล้ายกับของInputStreamคลาสมาก แม้ว่าจะมีความแตกต่างกันเล็กน้อยก็ตาม
int read()วิธี
เมธอดนี้อ่านหนึ่งรายการcharจากสตรีมและส่งกลับ ประเภทcharขยายเป็น an intแต่สองไบต์แรกของผลลัพธ์จะเป็นศูนย์เสมอ
int read(char[] buffer)วิธี
นี่คือตัวแปรที่สองของread()วิธีการ มันช่วยให้คุณอ่านอาร์เรย์ถ่านจากReaderทั้งหมดในครั้งเดียว อาร์เรย์ที่จะเก็บอักขระจะต้องผ่านเป็นอาร์กิวเมนต์ เมธอดส่งคืนตัวเลข — จำนวนอักขระที่อ่านจริง
skip(long n)วิธี
วิธีนี้ช่วยให้คุณข้ามอักขระ n ตัวแรกจากReaderวัตถุได้ มันทำงานเหมือนกับวิธีการแบบอะนาล็อกของInputStreamคลาส ทุกประการ ส่งกลับจำนวนอักขระที่ถูกข้ามจริง
boolean ready()วิธี
ส่งกลับtrueหากมีไบต์ที่ยังไม่ได้อ่านในสตรีม
void close()วิธี
เมธอดclose()จะปิดสตรีมข้อมูลและปล่อยทรัพยากรภายนอกที่เกี่ยวข้อง เมื่อสตรีมถูกปิด จะไม่สามารถอ่านข้อมูลได้อีก
สำหรับการเปรียบเทียบ ลองเขียนโปรแกรมที่คัดลอกไฟล์ข้อความ:
| รหัส | บันทึก |
|---|---|
|
Readerสำหรับอ่านจากไฟล์Writerสำหรับเขียนลงไฟล์บัฟเฟอร์ที่เราจะอ่านข้อมูล ตราบเท่าที่มีข้อมูลในสตรีม อ่านข้อมูลลงในบัฟเฟอร์ เขียนข้อมูลจากบัฟเฟอร์ไปยังสตรีมที่สอง |
GO TO FULL VERSION