Input Output /Stream
โปรแกรมคอมพิวเตอร์หนึ่งๆจะมีประสิทธิภาพสูงสุดนั้น ต้องสามารถโต้ตอบกับโลกภายนอกได้หรือสิ่งต่างๆรอบตัวได้ ไม่ใช่ทำงานภายในตัวมันเอง โดยการโต้ตอบดังกล่าวคือ การอ้างถึง Input/Output
โปรแกรมต่างๆต้องมีการเชื่อมโยงข้อมูลภายนอก โดยทำการเข้ามาใช้และประยุกต์ตามกลไกของโปรแกรม แล้วส่งไปที่ต่างๆ ในฮาร์ดดิสก์ หน่วยความจำ ระบบเครือข่าย หรือจากโปรแกรมต่างๆ(โดยข้อมูลอาจเป็นตัวอักษร รูปภาพ เสียง หรือออบเจ็กต์ใดก็ได้)
จากรูปโปรแกรมจะทำการอ่านหรือเขียนข้อมูลจากอุปกรณ์I/O ภายนอกโปรแกรม โดยมีสะพานส่งข้อมูลระหว่างกลาง เมื่อไรที่มีการส่งข้อมูลผ่านสะพานนี้ จาวาจะเรียกมันว่า Stream ซึ่งจะ๔กนำไปใช้ในกระบวนการของโปรแกรม
ในภาษาจาวา การอ่านเข้ามาหรือการส่งออกไปของ stream นั้นลำดับการเขียนจะเป็นแบบเดียวกันเสมอคือ การเปิด stream หรือสะพานเชื่อมโยงที่ถ่ายโอนข้อมูล จากนั้นก็ตรวจสอบว่าข้อมูลดังกล่าวถูกเปิดหรืออ่านหมดแล้วหรือยัง ถ้ายังก็จะทำจนกว่าจะหมด แล้วทำการปิดสะพาน ดังรูป
การทำงานที่เกี่ยวข้องกับ I/O จะแบ่งเป็นสองกลุ่มใหญ่ๆคือ ข้อมูลที่อยู่ในเครื่องอ่านออกเท่านั้น (Machine-formatted data) และข้อมูลที่เป็นภาษามนุษย์ (Human-readable data) ซึ่งสองชนิดของ Stream ที่ภาษาจาวาใช้สำหรับข้อมูลสองชนิดดังกล่าวก็คือ byte stream และ character stream ตามลำดับ
Byte Stream
Byte stream เป็นStream ที่จาวาใช้สำหรับการเขียนและการอ่านข้อมูลแบบเครื่อง (Machine-formatted data) โดยโครงสร้างคลาสย่อยขึ้นมาจากคลาส InputStream และ OutputStream ซึ่งการเขียนค่าข้อมูลหนึ่งออกไปด้วยการใช้ Output Stream นั้น ซึ่งไม่สามารถอ่านผลของการเขียนค่านั้นได้ด้วยตัวเอง ต้องอาศัยการกลับสู่คอมพิวเตอร์ด้วย InputStreamจากรูปไม่ว่าข้อมูลอะไรถ้าถูกเขียนเป็น OutputStream แล้ว ค่าดังกล่าวจะถูกเขียนเป็นภาษาเครื่องและถูกอ่านขึ้นมาเป็นภาษาเครื่อง โดยแสดงผลลัพธ์ออกเป็นสิ่งที่เขียนเข้ามาในตอนแรกได้ด้วย InputStream โดยการใช้ Byte Stream นี้เป็นการอ่านหรือเขียนข้อมูลที่เพิ่มประสิทธิภาพกับโปรแกรม เนื่องจากมันไม่ต้องมีการแปลภาษาเครื่องเป็นภาษามนุษย์
Character Stream
เป็นการอ่านและเขียนข้อมูลด้วยภาษาที่มนุษย์เข้าใจ โดยการสร้างออบเจ็กต์มาจากคลาสหลักสองคลาสคือ Reader และ Writer โดยทั้งสองต่างเกี่ยวกับกระบวนการแปลค่าจากข้อมูลเริ่มต้นเป็นค่าที่สามารถอ่านได้ และอยู่ในรูปเรียงกันของตัวอักษรในจำนวนบิตที่เหมาะสม
จากรูป ถ้ามีการเขียนค่าจากตัวเลข 250 เป็น Writer Stream คอมพิวเตอร์จะทำการแปลค่าตัวเลขนั้นให้ เป็นการเรียงกันของอักขระที่สามารถเข้าใจได้โดยมนุษย์ว่าเป็นตัวเลข ’250’ และการอ่านขึ้นมาด้วย Reader Stream นั้นเกี่ยวข้องกับการแปลสำหรับทำให้อักขระนั้นๆ กลับเป็นค่าตัวเลขที่ถูกเก็บไว้ในตัวแปรตัวเลขอีกที่หนึ่งได้
กระบวนการนี้เกิดขึ้นเช่นเดียวกับค่าเริ่มต้นที่เป็นข้อความหรืออักษรที่เข้าใจได้อยู่แล้ว เนื่องจากอยู่ในจำนวนบิตที่ต่างกัน เช่น อักษรจากในโปรแกรม Editor ต่างๆที่เก็บในรูปของค่า Unicode ซึ่งเก็บข้อมูล 16 บิต และสำหรับคนที่ใช้อักษรประเภท Western ที่ตัวอักษรถูกเก็บไว้ในไฟล์ที่เป็น ASEII ซึ่งแต่ละตัวอักษรจะใช้ 8 บิต
การจัดข้อมูลด้วย Stream
คลาส Steam ต่างๆที่กล่าวมาถูกกำหนดไว้ใน Package java.io ยังมีคลาสอื่นๆอีกที่รองรับการทำงานกับ Stream การเขียนโปรแกรมถ้าต้องการใช้คลาสที่กำหนดใน Package ให้ทำการ Import ไว้ที่ด้านบนของโปรแกรม
//Import java.io.*;
การอ่าน Stream
การอ่าน Stream ของออบเจ็กต์ที่สร้างจากคลาส InputStream และ Reader นั้นใช่เมธอดเดียวกัน
คือ read() ซึ่งใช้ได้ 3 แบบ
1.การอ่านข้อมูลทีละ byte
//public int read() throws IOException
เป็นการอ่านข้อมูลทีละ byte ถัดไปจาก Stream โดยคืนค่าเป็นจำนวนเต็มบวกที่มีค่าตั้งแต่ 0-255 และจะคืนค่าเป็น -1 ก็ต่อเมื่อมาถึงบิตสุดท้ายของ Stream แต่ถ้าเกิด error ก็จะแสดงค่า error จาก IOException หรือที่เรียกว่าเป็นการ Throw Exception
ตัวอย่าง yourClass2ReadStream.java
import java.io.*;
class yourClass2ReadStream
{ public static void main(String[] args) throw IOException
{ ClassInputStream in = new ClassInputStream();
int c;
while ((c = in.read()) ! = -1)
System.out.println("Next Byte = in.close();
“ClassInputStream” อาจจะเป็น CharArrayReader, FileReader, PipedReader, StringReader หรือ FileInputStream, PipedInputStream, ByteArrayInputStream, StringBufferInputStream ก็ได้ แล้วแต่ว่าเป็น Stream ของข้อมูลแบบไหน โดยถ้าทำการ read()
แล้วค่าที่ได้ยังไม่เท่ากับ -1 ก็ให้ทำต่อแล้วพิมพ์ค่าออกหน้าจอไปเรื่อยๆจนกว่าจะหมดค่า Streamหรือคืน
ค่าเป็น -1
2.การอ่านข้อมูลแบบอาร์เรย์ของ byte
เป็นการอ่านข้อมูลไบต์จำนวนหนึ่งจาก Stream ที่เก็บไว้ในอาร์เรย์ชั่วคราว b คืนค่าเป็นจำนวนครั้งของการอ่านโดยมีเงื่อนไขการคืนค่าดังนี้
> ถ้า b มีค่าเป็น null จะเกิด Error จาก NullPointerException
> คืนค่า 0 ถ้าขนาดของอาร์เรย์ b = 0 หรือไม่มีค่าใดๆ ในอาร์เรย์ คือไม่มีไบต์ใดๆ ถูกอ่าน
3.การอ่านข้อมูลแบบอาร์เรย์ของ byte แบบกำหนดขนาด
// public int read( byte[] b, int off, int len ) throw IOException
การเขียน Stream
เมื่อได้ Stream ที่มาจากการอ่านหัวข้อที่ผ่านมาหรือถูกกำหนดค่าโดยโปรแกรมการนำไปใช้ก็คือการเขียน Stream ไม่ว่าจะออกมาทางหน้าจอหรืออุปกรณ์ I/O ใดๆ จะใช้เมธอด write() มี 3 รูปแบบดังนี้
1.การเขียนทีละตัวอักษร โดย”c”แทนค่าของตัวอักษรนั้น
//public void write(int c) throws IOException
2.การเขียนแบบอาร์เรย์
//public void write(byte[] cbuf) throws IOException
3.การเขียนบางส่วนของอาร์เรย์ตัวอักษร
//public abstract void write(byte[] b,int off ,int len) throws IOException
เมธอด write() ทำการแปลงค่า int ที่อ่านมาจาก Stream เป็นตัวอักษรทันที ทั้ง 3 วิธีนี้ยังคล้ายกับเมธอด read() เนื่องจากบางครั้งเมื่อ Stream ถูกอ่านจะถูกนำมาเขียนทันที
ตัวอย่าง
import java.io.*;
class yourClass2ReadStream
{
public static void main(String[] args) throw IOException
{ ClassInputStream in = new ClassInputStream();
ClassOutputStream out = new ClassOutputStream();
int c;
while ((c = in.read()) ! = -1)
{
out.write(c);
}
}
}
“in” เป็น Stream ที่สร้างมาจาก Steam ชนิดใดก็ได้ ส่วน
“out”เป็น Stream ที่ต้องการเขียนลงไป
อุปกรณ์ที่เรารู้จักกันดีคือ Output ได้แก่ System.out ที่ให้ผลลัพธ์ออกมาทางหน้าจอเขียนได้ดังนี้
// System.out.write(c);
การทำงานกับแฟ้มข้อมูล
โดยทั่วไปที่เรารู้กันดีว่าโปรแกรมและข้อมูลต่างๆที่ทำงานอยู่ ณ เวลาใดๆ นั้นเกิดขึ้นที่หน่วยความจำหลักซึ่งเมื่อปิดเครื่องคอมพิวเตอร์ลง ทุกอย่างก็จะถูกล้างออกหมดทุกครั้งไป ดังนั้น File หรือแฟ้มข้อมูลจึงถูกสร้างขึ้นเพื่อการเก็บรักษาข้อมูลหรือโปรแกรมไว้ในดิสก์ชนิดต่างๆ เช่น ฮาร์ดดรสก์ ฟล็อปปี้ดิสก์ หรือซีดีรอมเพื่อสามารถที่จะนำข้อมูลหรือโปรแกรมเหล่านั้นกลับมาใช้ได้อีก
ไฟล์จะถูกจัดเก็บและแยกหมวดหมู่อย่างเป็นระเบียบไว้ในไดเรคทอรีหรือที่บางครั้งเรียกว่าโฟลเดอร์ ซึ่งไดเร็คทอรีนี้จะทำการจัดเก็บทั้งไฟล์และไดเร็คทอรีอื่นๆ เอาไว้ โดยเราจะแยกความแตกต่างระหว่างไฟล์หรือโฟลเดอร์ต่างๆ ได้ด้วยชื่อของมัน (Name)
การทำงานของโปรแกรมและข้อมูลที่เกี่ยวข้องกันก็คือ โปรแกรมสามารที่จะอ่านข้อมูลขึ้นจากไฟล์ หรือเขียนข้อมูลลงไปในไฟล์ ไม่ว่าจะเป็น ไฟล์ที่มีอยู่แล้วหรือว่าจะเป็นการสร้างไฟล์นั้นขึ้นมาใหม่ จากที่กล่าวมานี้สามารถทำได้ผ่าน Stream
รู้จักกับ File Stream
Stream ที่จาวาเตรียมไว้ให้มากมายหลายชนิด แต่ดูเหมือนว่า File Stream จะเป็นชนิดที่เราสามารถทำความเข้าใจกับมันได้ง่ายที่สุด โดยมันประกอบไปด้วยคลาสย่อยดังนี้
FileReader, FileWriter – ถูกใช้สำหรับการสร้าง Stream เพื่อการอ่านและเขียนลงไฟล์แบบใช้ภาษามนุษย์
FileInputStream, FileOutputStream – ถูกใช้สำหรับการสร้าง Stream เพื่อการอ่านและเขียนลงไฟล์แบบภาษาเครื่อง
คลาส Stream สามารถแบ่งออกเป็นสองคลาสใหญ่ๆสำหรับการสร้าง Stream ชนิดต่างๆ โดยสามารถอธิบายที่มาของ File Stream ทั้ง 4 ชนิดที่กล่าวมาได้ดังนี้
Human/readable stream-->Writer-->FileWriter-->Human-readable file format
-->Reader-->FileReader
Machine-format stream-->OutputStream-->FileOutputStream-->Machine file format
-->InputStream-->FileInputStream