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