สวัสดี! บทเรียนและงานในระดับ 3 จะสอนวิธีแสดงข้อมูลบนคอนโซล และวิธีอ่านข้อมูลจากแป้นพิมพ์ในอีกทิศทางหนึ่ง
คุณยังได้เรียนรู้การใช้โครงสร้างที่ซับซ้อนต่อไปนี้เพื่อทำสิ่งนี้ให้สำเร็จ:
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
แต่มีคำถามหนึ่งที่เรายังไม่ได้ตอบ
มันทำงานอย่างไรในโลกนี้?
ในความเป็นจริง โปรแกรมต่างๆ แทบไม่มีความเป็นอิสระจากกันโดยสิ้นเชิง พวกเขาสื่อสารกับโปรแกรม ระบบ อินเทอร์เน็ต ฯลฯ โดย "สื่อสาร" เราหมายถึง "แลกเปลี่ยนข้อมูล" เป็นหลัก นั่นคือพวกเขาได้รับข้อมูลภายนอกและส่งข้อมูลโปรแกรมภายในไปที่ไหนสักแห่ง ตัวอย่างโปรแกรมแลกเปลี่ยนข้อมูลที่มีอยู่มากมายในชีวิตประจำวัน ตัวอย่างเช่น เว็บไซต์จำนวนมากให้คุณลงชื่อเข้าใช้ด้วยบัญชี Facebook หรือ Twitter แทนการลงทะเบียน ในสถานการณ์นี้ โปรแกรมสองโปรแกรม (เช่น Twitter และเว็บไซต์ที่คุณลงชื่อเข้าใช้) จะแลกเปลี่ยนข้อมูลที่จำเป็น ผลสุดท้ายคือคุณลงชื่อเข้าใช้สำเร็จ คำว่า"สตรีม"ใช้เพื่ออธิบายกระบวนการแลกเปลี่ยนข้อมูล ชื่อนี้มาจากไหน? จากประสบการณ์ของคุณ "ลำธาร" อาจเกี่ยวข้องกับแม่น้ำมากกว่าการเขียนโปรแกรม นั่นไม่ใช่เรื่องบังเอิญ :) โดยพื้นฐานแล้วสตรีมคือชิ้นส่วนของข้อมูลที่เคลื่อนไหว กล่าวอีกนัยหนึ่ง ในการเขียนโปรแกรม ไม่ใช่น้ำที่ไหล แต่เป็นข้อมูลในรูปของไบต์และอักขระ เราสามารถรับบิตข้อมูลจากสตรีมข้อมูลแล้วนำไปใช้ได้ อีกครั้ง เราจะใช้การเปรียบเทียบน้ำ/การไหล: คุณสามารถตักน้ำจากแม่น้ำเพื่อทำซุป ดับไฟ หรือรดน้ำดอกไม้ของคุณ สตรีมช่วยให้คุณทำงานกับแหล่งข้อมูลใดก็ได้ ไม่ว่าจะเป็นอินเทอร์เน็ต ระบบไฟล์ของคอมพิวเตอร์ของคุณ หรืออย่างอื่น ก็ไม่สร้างความแตกต่าง สตรีมเป็นเครื่องมือสากล พวกเขาอนุญาตให้โปรแกรมรับข้อมูลจากทุกที่ (สตรีมอินพุต) และส่งได้ทุกที่ (สตรีมเอาต์พุต) งานของพวกเขาเหมือนกัน: รับข้อมูลจากที่หนึ่งและส่งไปยังอีกที่หนึ่ง สตรีมมีสองประเภท:- สตรีม อินพุตใช้เพื่อรับข้อมูล
- เอาต์พุต สตรีมสำหรับการส่งข้อมูล
InputStream
and OutputStream
คลาส แต่สตรีมสามารถจัดประเภทได้อีกทางหนึ่ง นอกจากสตรีมอินพุตและเอาท์พุตแล้ว เรายังพูดถึงไบต์สตรีมและสตรีมอักขระ ด้วย ความหมายในที่นี้ควรชัดเจนเพียงพอ: ไบต์สตรีมจะส่งข้อมูลเป็นชุดของไบต์ ในขณะที่สตรีมอักขระจะส่งเป็นชุดอักขระ ในบทเรียนนี้ เราจะพูดถึงอินพุตสตรีม ฉันจะใส่ลิงก์ที่มีข้อมูลเกี่ยวกับเอาต์พุตสตรีมไว้ที่ท้ายบทเรียน คุณสามารถอ่านได้ด้วยตัวคุณเอง :) ตอนนี้ดูที่รหัสนี้:
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
เมื่อผ่านบทเรียน คุณไม่คิดว่าบรรทัดนี้ค่อนข้างน่ากลัวหรือไม่? :) นั่นจะไม่เป็นเช่นนั้นเมื่อเราได้สำรวจวิธีการทำงานแล้ว มาทำสิ่งที่ถูกต้องกันเถอะ เราจะเริ่มต้นในตอนท้าย System.in
เป็นInputStream
วัตถุ ตัวอย่างของคลาสที่เราพูดถึงในช่วงต้น เป็นสตรีมอินพุตที่เชื่อมโยงกับอุปกรณ์อินพุตของระบบ (แป้นพิมพ์) อย่างไรก็ตาม คุณคุ้นเคยกับสตรีมนี้ทางอ้อม ท้ายที่สุด คุณมักจะใช้ "เพื่อนร่วมงาน" ของมัน — System.out
! System.out
เป็นสตรีมเอาต์พุต ของระบบ ใช้เพื่อส่งข้อมูลออกไปยังคอนโซลด้วยวิธีที่คุณชื่นชอบSystem.out.println()
ซึ่งคุณใช้เป็นประจำ :) System.out
เป็นสตรีมสำหรับการส่งข้อมูลไปยังคอนโซลในขณะที่System.in
มีไว้สำหรับรับข้อมูลจากแป้นพิมพ์ ง่ายนิดเดียว :) ยิ่งไปกว่านั้น เราสามารถอ่านข้อมูลจากคีย์บอร์ดได้โดยไม่ต้องใช้โครงสร้างขนาดใหญ่นี้ เราสามารถเขียน: System.in.read()
;
public class Main {
public static void main(String[] args) throws IOException {
while (true) {
int x = System.in.read();
System.out.println(x);
}
}
}
คลาสInputStream
(จำไว้ว่าSystem.in
เป็นInputStream
วัตถุ) มีread()
เมธอดที่ให้คุณอ่านข้อมูลได้ มีปัญหาอย่างหนึ่ง: มันอ่านbytesไม่ใช่character การใช้ตัวอักษรภาษาอังกฤษเพียงอย่างเดียวเป็นเรื่องน่าเบื่อ ดังนั้นลองอ่านตัวอักษรจีน "魚" จากแป้นพิมพ์ (เพียงคัดลอกตัวอักษรนี้จากที่นี่และวางลงในคอนโซลโดยใช้ ctrl + vบนพีซีหรือCommand + vบน Mac) อักขระนี้หมายถึง 'ปลา' โดยวิธีการ เอาต์พุตคอนโซล: 魚 233 173 154 10 สัญลักษณ์นี้และภาษาจีนอื่นๆ จำนวนมากใช้ 3 ไบต์ในหน่วยความจำของคอมพิวเตอร์ (ต่างจากตัวอักษรละตินที่ใช้เพียง 1 ไบต์) ในกรณีนี้ 4 ไบต์ถูกอ่านจากสตรีม: สามไบต์แรกแทนอักขระ "魚" และไบต์อื่นๆ แทนบรรทัดใหม่ (Enter) ดังนั้นSystem.in
ในรูปแบบที่ปราศจากการตกแต่งจึงไม่ใช่ตัวเลือกสำหรับเรา มนุษย์ (มีข้อยกเว้นที่หายาก!) ไม่รู้วิธีอ่านไบต์ แต่ InputStreamReader
ชั้นมาช่วยทัน! มาดูกันว่านี่คือสัตว์ชนิดใด
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
เราส่งผ่านSystem.in
ไปยังวัตถุInputStreamReader ชื่อชั้นบอกเลย! เราสร้างInputStreamReader
ออบเจกต์และส่งผ่านอินพุตสตรีมที่มันจะอ่านข้อมูล ในกรณีนี้...
new InputStreamReader(System.in)
...เราบอกมันว่า "คุณจะอ่านข้อมูลจากสตรีมอินพุตของระบบ (จากแป้นพิมพ์)" แต่นี่ไม่ใช่หน้าที่เดียว! ไม่InputStreamReader
ได้รับข้อมูลจากสตรีมเท่านั้น นอกจากนี้ยังแปลงไบต์สตรีมเป็นสตรีมอักขระ กล่าวอีกนัยหนึ่ง คุณไม่จำเป็นต้องแปลงข้อมูลจาก "หนึ่งและศูนย์" เป็น "ภาษาที่มนุษย์อ่านได้" อีกต่อไป InputStreamreader
ทำทุกอย่างเพื่อคุณ แน่นอนInputStreamReader
ไม่ จำกัด เฉพาะการอ่านข้อมูลจากคอนโซล สามารถอ่านข้อมูลจากที่อื่นได้ด้วย ตัวอย่างเช่น จากไฟล์:
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
public class Main {
public static void main(String[] args) throws IOException {
InputStreamReader inputStreamReader = new InputStreamReader(new FileInputStream("C:\\Users\\username\\Desktop\\testFile.txt"));
}
}
ที่นี่เราสร้างFileInputStream
(หนึ่งรสชาติของInputStream
) ส่งผ่านเส้นทางของไฟล์ และส่งสตรีมไปยังไฟล์InputStreamReader
. ตอนนี้จะสามารถอ่านข้อมูลจากไฟล์ได้ (หากไฟล์มีอยู่จริงที่เส้นทาง) เรายังใช้ วิธีการ InputStreamReader
ของคลาสread()
เพื่ออ่านข้อมูล (แหล่งที่มาของข้อมูลไม่สำคัญ: คอนโซล ไฟล์ หรือที่อื่น) System.in.read()
และ ?\ ต่างกันอย่างไรInputStreamReader.read()
มาลองอ่านอักขระ "魚" อีกครั้งด้วยInputStreamReader
เครื่องหมาย ฉันเตือนคุณถึงสิ่งที่อ่านโดยSystem.in.read()
: 魚 233 173 154 10 แล้วสิ่งInputStreamReader
เดียวกันนี้ทำงาน อย่างไร
public class Main {
public static void main(String[] args) throws IOException {
InputStreamReader reader = new InputStreamReader(System.in);
while (true) {
int x = reader.read();
System.out.println(x);
}
}
}
เอาต์พุตของคอนโซล: 魚 39770 10 ความแตกต่างนั้นชัดเจนในทันที ไบต์สุดท้าย (แทนบรรทัดใหม่) ยังคงไม่เปลี่ยนแปลง (หมายเลข 10) แต่อักขระ "魚" ถูกแปลงเป็นรหัสเดียว "39770" นี่คือความหมายของการอ่านอักขระ! หากคุณไม่เชื่อว่า 39770 แทนตัวอักษร "魚" คุณก็สามารถโน้มน้าวตัวเองได้ง่ายๆ :)
import java.io.IOException;
public class Main {
public static void main(String[] args) throws IOException {
char x = 39770;
System.out.println(x);
}
}
เอาต์พุตคอนโซล: 魚 แต่หากInputStreamReader
ดีมาก ทำไมเราถึงต้องการด้วยBufferedReader
? InputStreamReader
รู้วิธีอ่านข้อมูลและแปลงไบต์เป็นอักขระ เราจะขออะไรอีก ทำไมผู้อ่านคนอื่น? :/ คำตอบนั้นง่ายมาก: เพื่อประสิทธิภาพและ ความ สะดวกสบาย ที่มากขึ้น เริ่มจากประสิทธิภาพกันก่อน เมื่อBufferedReader
อ่านข้อมูล จะใช้พื้นที่พิเศษที่เรียกว่าบัฟเฟอร์ ซึ่งจะ "เก็บ" อักขระที่อ่าน ท้ายที่สุด เมื่ออักขระเหล่านี้จำเป็นต้องใช้ในโปรแกรม อักขระเหล่านี้จะถูกดึงมาจากบัฟเฟอร์ ไม่ใช่จากแหล่งข้อมูลโดยตรง (แป้นพิมพ์ ไฟล์ ฯลฯ) ช่วยประหยัดทรัพยากรได้มาก เพื่อให้เข้าใจถึงวิธีการทำงาน ลองนึกภาพพนักงานส่งของในบริษัทขนาดใหญ่ คนส่งของนั่งอยู่ในสำนักงานเพื่อรอใครสักคนนำพัสดุมาส่ง ทุกครั้งที่เขาได้รับแพ็คเกจใหม่ เขาสามารถออกเดินทางได้ทันที แต่อาจมีแพ็คเกจจำนวนมากในระหว่างวัน เขาจะต้องเดินทางหลายครั้งระหว่างสำนักงานและที่อยู่จัดส่ง คนส่งของจะวางกล่องไว้ในที่ทำงานของเขาแทน ทุกคนใส่ของลงในกล่อง ตอนนี้ผู้จัดส่งสามารถรับกล่องและย้ายจากที่อยู่หนึ่งไปยังอีกที่อยู่หนึ่งได้อย่างใจเย็น สิ่งนี้ช่วยประหยัดเวลาได้มากเพราะเขาไม่ต้องกลับไปที่สำนักงานทุกครั้ง ในตัวอย่างนี้ กล่องเป็นเพียงบัฟเฟอร์ และสำนักงานเป็นแหล่งข้อมูล พนักงานส่งของรับพัสดุจากกล่องเดียวเมื่อทำการจัดส่งได้ง่ายกว่าการกลับไปที่สำนักงานทุกครั้ง เขาจะประหยัดน้ำมันด้วย ในทำนองเดียวกัน ในโปรแกรม การนำข้อมูลจากบัฟเฟอร์มาใช้ทรัพยากรน้อยกว่าการอ้างถึงแหล่งข้อมูลในแต่ละครั้ง ผลที่ตามมา,BufferedReader
+ InputStreamReader
เร็วกว่าInputStreamReader
คนเดียว เราได้พิจารณาประสิทธิภาพแล้ว สิ่งที่เกี่ยวกับความสะดวกสบาย? ข้อได้เปรียบหลักคือBufferedreader
สามารถอ่านข้อมูลได้ไม่เพียงแค่ครั้งละหนึ่งอักขระเท่านั้น (แม้ว่าจะทำได้ด้วยread()
วิธีการของมันก็ตาม) แต่ยังสามารถอ่านได้ทั้งบรรทัดในแต่ละครั้งด้วย! ทำได้โดยใช้readLine()
วิธีการ
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
String s = reader.readLine();
System.out.println("We read this line from the keyboard:");
System.out.println(s);
}
}
เอาต์พุตคอนโซล: CodeGym เป็นเว็บไซต์ที่ดีที่สุดสำหรับการเรียนรู้ Java! เราอ่านบรรทัดนี้จากแป้นพิมพ์: CodeGym เป็นเว็บไซต์ที่ดีที่สุดสำหรับการเรียนรู้ Java! สิ่งนี้มีประโยชน์อย่างยิ่งเมื่ออ่านข้อมูลจำนวนมาก การอ่านข้อความทีละหนึ่งหรือสองบรรทัดยังคงเป็นไปได้ แต่การอ่านใน "สงครามและสันติภาพ" ทีละตัวอักษรอาจเป็นปัญหาเล็กน้อย :)
อ่านเพิ่มเติม: |
---|
GO TO FULL VERSION