สวัสดี! วันนี้เราจะพูดถึงชั้นเรียน
จริงๆ แล้ว คุณคุ้นเคยกับสองวิธีของคลาสอยู่
คุณอาจลืมไปแล้วว่ามันคืออะไร
PrintStream
และทุกสิ่งที่ชั้นเรียนสามารถทำได้ PrintStream
แล้ว print()
นี่คือ และเมธอดprintln()
ที่คุณอาจใช้ทุกวัน :) เนื่องจากตัวแปรSystem.out
คืออ็อบเจ็กต์PrintStream
เมื่อคุณเรียกเมธอดSystem.out.println()
คุณกำลังเรียกเมธอดของคลาสนี้โดยเฉพาะ วัตถุประสงค์ทั่วไปของคลาสPrintStream
คือเพื่อส่งออกข้อมูลไปยังสตรีมบางส่วน คลาสนี้มีตัวสร้างหลายตัว นี่คือบางส่วนที่พบบ่อยที่สุด:
PrintStream(OutputStream outputStream)
PrintStream(File outputFile) throws FileNotFoundException
PrintStream(String outputFileName) throws FileNotFoundException
PrintStream
ได้ เช่น ชื่อของไฟล์ที่เราต้องการส่งออกข้อมูล หรืออีกทางหนึ่งคือวัตถุนั้นFile
เอง มาดูกันว่าวิธีนี้ทำงานอย่างไรพร้อมตัวอย่าง:
import java.io.File;
import java.io.FileNotFoundException;
import java.io.PrintStream;
public class Main {
public static void main(String arr[]) throws FileNotFoundException
{
PrintStream filePrintStream = new PrintStream(new File("C:\\Users\\Username\\Desktop\\test.txt"));
filePrintStream.println(222);
filePrintStream.println("Hello world");
filePrintStream.println(false);
}
}
โค้ดนี้จะสร้างไฟล์บนเดสก์ท็อปtest.txt
(หากไม่มีอยู่แล้ว) และเขียนตัวเลข สตริง และboolean
-variable ของเราตามลำดับ นี่คือเนื้อหาของไฟล์ของเราหลังจากที่โปรแกรมทำงาน:
222
Hello world!
false
ดังที่เราได้กล่าวไว้ข้างต้น ไม่จำเป็นต้องส่งผ่านตัววัตถุไฟล์นั้นFile
เอง คุณเพียงแค่ต้องระบุเส้นทางไปในตัวสร้าง:
import java.io.FileNotFoundException;
import java.io.PrintStream;
public class Main {
public static void main(String arr[]) throws FileNotFoundException
{
PrintStream filePrintStream = new PrintStream("C:\\Users\\Username\\Desktop\\test.txt");
filePrintStream.println(222);
filePrintStream.println("Hello world");
filePrintStream.println(false);
}
}
รหัสนี้จะทำเช่นเดียวกับรหัสก่อนหน้า อีกวิธีที่น่าสนใจในการดูคือprintf()
หรือจัดรูปแบบเอาต์พุตสตริง "สตริงที่จัดรูปแบบ" หมายถึงอะไร เพื่ออธิบายฉันจะยกตัวอย่าง:
import java.io.IOException;
import java.io.PrintStream;
public class Main {
public static void main(String[] args) throws IOException {
PrintStream printStream = new PrintStream("C:\\Users\\Евгений\\Desktop\\test.txt");
printStream.println("Hello!");
printStream.println("I'm robot!");
printStream.printf("My name is %s, my age is %d!", "Amigo", 18);
printStream.close();
}
}
ที่นี่ แทนที่จะจดชื่อและอายุของหุ่นยนต์ของเราไว้อย่างชัดเจนในบรรทัด ดูเหมือนว่าเราจะปล่อยให้ "พื้นที่ว่าง" สำหรับข้อมูลนี้โดยใช้พอยน์เตอร์%s
และ%d
. และเราส่งข้อมูลที่ควรอยู่ในตำแหน่งเหล่านี้เป็นพารามิเตอร์ ในกรณีของเรา นี่คือสตริง " Amigo " และหมายเลข 18 ตัวอย่างเช่น เราสามารถสร้างช่องว่างอื่น: พูด%b
และส่งพารามิเตอร์อื่น มีไว้เพื่ออะไร? ก่อนอื่นเพื่อเพิ่มความยืดหยุ่น หากโปรแกรมของคุณจำเป็นต้องแสดงข้อความต้อนรับบ่อยครั้ง คุณจะต้องป้อนข้อความที่จำเป็นสำหรับหุ่นยนต์ใหม่แต่ละตัวด้วยตนเอง คุณจะไม่สามารถใส่ข้อความนี้ลงในค่าคงที่ได้: ชื่อและอายุของทุกคนแตกต่างกัน! แต่เมื่อใช้วิธีการใหม่ คุณสามารถส่งออกสตริงที่มีคำทักทายเป็นค่าคงที่ได้ และหากจำเป็น เพียงเปลี่ยนพารามิเตอร์ในวิธีการprintf()
นั้น
import java.io.IOException;
import java.io.PrintStream;
public class Main {
private static final String GREETINGS_MESSAGE = "My name is %s, my age is %d!";
public static void main(String[] args) throws IOException {
PrintStream printStream = new PrintStream("C:\\Users\\Евгений\\Desktop\\test.txt");
printStream.println("Hello!");
printStream.println("We are robots!");
printStream.printf(GREETINGS_MESSAGE, "Amigo", 18);
printStream.printf(GREETINGS_MESSAGE, "R2-D2", 35);
printStream.printf(GREETINGS_MESSAGE, "C-3PO", 35);
printStream.close();
}
}
ระบบในการปลอมแปลง
ในการบรรยายนี้ เราจะ "ต่อสู้กับระบบ" และเรียนรู้วิธีการแทนที่ตัวแปรSystem.in
และเปลี่ยนเส้นทางเอาต์พุตของระบบไปยังตำแหน่งที่เราต้องการ 
System.in
แต่ไม่มีนักเรียน JavaRush คนไหนที่จะลืมโครงสร้างนี้:
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
System.in
(like System.out
) เป็นตัวแปรคลาสแบบคงSystem
ที่ แต่ต่างจาก ตรงSystem.out
ที่เป็นของคลาสอื่น กล่าวคือInputStream
ของ ตามค่าเริ่มต้นSystem.in
นี่คือเธรดที่อ่านข้อมูลจากอุปกรณ์ระบบ—คีย์บอร์ด อย่างไรก็ตาม ในกรณีของSystem.out
เราสามารถแทนที่แหล่งข้อมูลได้ และการอ่านจะไม่เกิดขึ้นจากแป้นพิมพ์ แต่มาจากสถานที่ที่เราต้องการ! ลองดูตัวอย่าง:
import java.io.*;
public class Main {
public static void main(String[] args) throws IOException {
String greetings = "Hello! Меня зовут Амиго!\nЯ изучаю Java на сайте JavaRush.\nОднажды я стану крутым программистом!\n";
byte[] bytes = greetings.getBytes();
InputStream inputStream = new ByteArrayInputStream(bytes);
System.setIn(inputStream);
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
String str;
while ((str = reader.readLine())!= null) {
System.out.println(str);
}
}
}
แล้วเราทำอะไร? มักจะSystem.in
"ผูก" กับแป้นพิมพ์ แต่เราไม่ต้องการให้อ่านข้อมูลจากแป้นพิมพ์: ปล่อยให้อ่านจากบรรทัดข้อความปกติ! เราสร้างสตริงและรับมาเป็นอาร์เรย์ไบต์ ทำไมเราต้องมีไบต์? ความจริงก็คือว่ามันInputStream
เป็นคลาสนามธรรม และเราไม่สามารถสร้างอินสแตนซ์ของมันได้ คุณจะต้องเลือกชนชั้นจากทายาทของมัน เช่น เราสามารถเอาByteArrayInputStream
. มันเรียบง่าย และเพียงชื่อก็ชัดเจนว่ามันทำงานอย่างไร: แหล่งข้อมูลคืออาร์เรย์ไบต์ ดังนั้นเราจึงสร้างอาร์เรย์ไบต์เดียวกันนี้และส่งผ่านไปยังตัวสร้างของเราstream
ซึ่งจะอ่านข้อมูล จริงๆ แล้วทุกอย่างพร้อมแล้ว! ตอนนี้เราเพียงแค่ต้องใช้วิธีการSystem.setIn()
เพื่อตั้งค่าของตัวแปรอย่างin
ชัดเจน ในกรณีของout
อย่างที่คุณจำได้ มันเป็นไปไม่ได้อย่างชัดเจนที่จะตั้งค่าของตัวแปรเช่นกัน: คุณต้องใช้วิธีการsetOut()
พิเศษ หลังจากที่เรากำหนดInputStream
ตัวแปร ที่เราสร้างขึ้น System.in
แล้ว เราจำเป็นต้องตรวจสอบว่าแนวคิดของเราได้ผลหรือไม่ เพื่อนเก่าจะช่วยเราในเรื่องนี้ - BufferedReader
. ในสถานการณ์ปกติ รหัสนี้จะทำให้คอนโซลเปิดใน Intellij IDea ของคุณ และข้อมูลที่คุณป้อนจากแป้นพิมพ์จะถูกอ่านจากที่นั่น
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
String str;
while ((str = reader.readLine())!= null) {
System.out.println(str);
}
แต่เมื่อคุณรันตอนนี้ คุณจะเห็นว่าข้อความของเราจากโปรแกรมจะถูกส่งออกไปยังคอนโซล จะไม่มีการอ่านจากแป้นพิมพ์ เราได้เปลี่ยนแหล่งข้อมูลแล้ว ตอนนี้ไม่ใช่คีย์บอร์ด แต่เป็นสตริงของเรา! มันง่ายและเรียบง่ายมาก :) ในการบรรยายวันนี้ เราได้ทำความคุ้นเคยกับคลาสใหม่และได้ดู "แฮ็ก" เล็กๆ ใหม่สำหรับการทำงานกับ I/O ได้เวลากลับเข้าสู่คอร์สและแก้ไขปัญหากันสักที :) พบกันใหม่ในการบรรยายครั้งต่อไป!
GO TO FULL VERSION