โค้ดยิม/จาวาบล็อก/สุ่ม/ฝึกฝนการทำงานกับคลาส BuffreredReader และ InputStreamReade...
John Squirrels
ระดับ
San Francisco

ฝึกฝนการทำงานกับคลาส BuffreredReader และ InputStreamReader

เผยแพร่ในกลุ่ม
สวัสดี! บทเรียนวันนี้จะแบ่งออกเป็นสองส่วนเพื่อความสะดวก เราจะพูดซ้ำหัวข้อเก่าที่เราพูดถึงไปก่อนหน้านี้ และเราจะพิจารณาคุณสมบัติใหม่บางอย่าง :) เรามาเริ่มกันที่ข้อแรก คุณมีคลาสBufferedReaderหลายครั้ง แล้ว ฉันหวังว่าคุณจะไม่มีเวลาลืมข้อความนี้:
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
ก่อนอ่านเพิ่มเติม ให้ลองนึกถึงส่วนประกอบแต่ละอย่าง — System.in, InputStreamReader, BufferedReader— มีหน้าที่รับผิดชอบและเหตุใดจึงจำเป็น คุณจำได้ไหม? ถ้าไม่ก็ไม่ต้องกังวล :) หากคุณลืมบางสิ่งไป ให้อ่านบทเรียนนี้ อีกครั้ง ซึ่งมีไว้สำหรับชั้นเรียนผู้อ่านโดยเฉพาะ เราจะจำสั้น ๆ ว่าแต่ละคนสามารถทำอะไรได้บ้าง System.in— นี่คือสตรีมสำหรับรับข้อมูลจากแป้นพิมพ์  โดยหลักการแล้ว แค่ใช้ตรรกะที่จำเป็นในการอ่านข้อความก็เพียงพอแล้ว แต่อย่างที่คุณจำSystem.inได้ อ่านได้เฉพาะไบต์ ไม่ใช่อักขระ:
public class Main {

   public static void main(String[] args) throws IOException {

       while (true) {
           int x = System.in.read();
           System.out.println(x);
       }
   }
}
ถ้าเรารันโค้ดนี้และป้อนอักษรซีริลลิก "Й" ผลลัพธ์จะเป็น:
Й
208
153
10
อักขระซิริลลิกใช้หน่วยความจำ 2 ไบต์ และแสดงบนหน้าจอ ตัวเลข 10 คือการแสดงทศนิยมของอักขระป้อนบรรทัด เช่น จากการกด Enter การอ่านไบต์เป็นเรื่องที่น่ายินดี ดังนั้นการใช้งานSystem.inจึงไม่สะดวกนัก เพื่อให้อ่านอักษรซิริลลิก (และอื่นๆ) ได้อย่างถูกต้อง เราใช้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);
       }
   }
}
เราป้อนตัวอักษรเดียวกัน "Й" แต่ผลลัพธ์จะแตกต่างออกไปในครั้งนี้:
Й
1049
10
InputStreamReaderแปลงสองไบต์ (208 และ 153) เป็นเลขตัวเดียว 1049 นี่คือความหมายของการอ่านอักขระ 1,049 ตรงกับอักษรซีริลลิก "Й" เราสามารถโน้มน้าวตัวเองได้อย่างง่ายดายว่านี่คือความจริง:
public class Main {

   public static void main(String[] args) throws IOException {
       char x = 1049;
       System.out.println(x);
   }
}
เอาต์พุตคอนโซล:
Й
และเช่นเดียวกับforBufferedReader(และโดยทั่วไปBufferedAnythingYouWant) คลาสบัฟเฟอร์จะถูกใช้เพื่อเพิ่มประสิทธิภาพ การเข้าถึงแหล่งข้อมูล (ไฟล์ คอนโซล ทรัพยากรบนเว็บ) มีค่าใช้จ่ายค่อนข้างแพงในแง่ของประสิทธิภาพ ดังนั้นเพื่อลดจำนวนการเข้าถึงBufferedReaderอ่านและสะสมข้อมูลในบัฟเฟอร์พิเศษ และเราได้รับจากที่นั่น เป็นผลให้จำนวนครั้งที่เข้าถึงแหล่งข้อมูลถูกเฉือน — อาจมีหลายลำดับความสำคัญ! อีกคุณสมบัติหนึ่งBufferedReaderและข้อดีที่เหนือกว่าแบบธรรมดาInputStreamReaderคือ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 ("The user entered the following text:");
       System.out.println(s);
       reader.close();
   }
}
BufferedReader+InputStreamReader is faster than InputStreamReader alone
The user entered the following text:
BufferedReader+InputStreamReader is faster than InputStreamReader alone
ฝึกฝนการทำงานกับคลาส BuffreredReader และ InputStreamReader - 2แน่นอนBufferedReaderมีความยืดหยุ่นมาก คุณไม่จำกัดการทำงานกับแป้นพิมพ์เท่านั้น ตัวอย่างเช่น คุณสามารถอ่านข้อมูลได้โดยตรงจากเว็บ เพียงแค่ส่ง URL ที่จำเป็นไปยังผู้อ่าน:
public class URLReader {

   public static void main(String[] args) throws Exception {

       URL oracle = new URL("https://www.oracle.com/index.html");
       BufferedReader in = new BufferedReader(
               new InputStreamReader(oracle.openStream()));

       String inputLine;
       while ((inputLine = in.readLine()) != null)
           System.out.println(inputLine);
       in.close();
   }
}
คุณสามารถอ่านข้อมูลจากไฟล์โดยผ่านเส้นทางไฟล์:
public class Main {

   public static void main(String[] args) throws Exception {

       FileInputStream fileInputStream = new FileInputStream("testFile.txt");
       BufferedReader reader = new BufferedReader(new InputStreamReader(fileInputStream));

       String str;

       while ((str = reader.readLine()) != null)   {
           System.out.println (str);
       }

       reader.close();
   }
}

แทนที่ System.out

ทีนี้มาดูความสามารถที่น่าสนใจที่เรายังไม่เคยสัมผัสมาก่อน อย่างที่คุณจำได้แน่นอนSystemคลาสมีฟิลด์สแตติกสองฟิลด์— System.inและ System.outพี่น้องฝาแฝดเหล่านี้เป็นวัตถุกระแส System.inเป็นInputStream. และSystem.out เป็นPrintStream. ในตอนนี้เราจะพูด  System.outถึง ถ้าเราใส่Systemซอร์สโค้ดของคลาส เราจะเห็นสิ่งนี้:
public final class System {
……………...
public final static PrintStream out = null;
 …………
}
ดังนั้นจึง  System.out  เป็นเพียงตัวแปรคงที่ธรรมดาของSystemคลาส ไม่มีอะไรวิเศษเกี่ยวกับมัน :) outตัวแปรคือPrintStreamการอ้างอิง นี่เป็นคำถามที่น่าสนใจ: เมื่อใดSystem.out.println()ที่ดำเนินการ เหตุใดเอาต์พุตจึงไปที่คอนโซล ไม่ใช่ที่อื่น และสิ่งนี้สามารถเปลี่ยนแปลงได้หรือไม่? ตัวอย่างเช่น สมมติว่าเราต้องการอ่านข้อมูลจากคอนโซลและเขียนลงในไฟล์ข้อความ เป็นไปได้ไหมที่จะใช้สิ่งนี้เพียงแค่ใช้  System.outคลาสตัวอ่านและตัวเขียนเพิ่มเติม จริงอยู่ :) และเราสามารถทำได้แม้ว่าSystem.outตัวแปรจะถูกทำเครื่องหมายด้วยfinalตัวดัดแปลง!  ฝึกทำงานกับคลาส BuffreredReader และ InputStreamReader - 3แล้วเราต้องทำอย่างไรจึงจะทำให้สิ่งนี้เกิดขึ้น? ก่อนอื่น เราต้องการPrintStreamวัตถุใหม่เพื่อแทนที่วัตถุปัจจุบัน วัตถุปัจจุบันตั้งอยู่ในSystemคลาสตามค่าเริ่มต้นไม่ตอบสนองวัตถุประสงค์ของเรา: มันชี้ไปที่คอนโซล คุณต้องสร้างไฟล์ใหม่ที่ชี้ไปที่ไฟล์ข้อความ ซึ่งเป็น "ปลายทาง" สำหรับข้อมูลของเรา ประการที่สอง เราต้องเข้าใจวิธีการกำหนดค่าใหม่ให้กับSystem.outตัวแปร คุณไม่สามารถใช้ตัวดำเนินการกำหนดอย่างง่ายได้ เนื่องจากตัวแปรถูกทำเครื่องหมายfinalไว้ มาทำงานกันต่อจากจุดสิ้นสุด เมื่อมันเกิดขึ้นSystemคลาสมีเมธอดที่เราต้องการ: setOut(). ใช้PrintStreamวัตถุและตั้งค่าเป็นปลายทางสำหรับเอาต์พุต นั่นคือสิ่งที่เราต้องการ! สิ่งที่เหลืออยู่คือการสร้างPrintStreamวัตถุ นี่เป็นเรื่องง่ายเช่นกัน:
PrintStream filePrintStream = new PrintStream(new File("C:\\Users\\Username\\Desktop\\test.txt"));
รหัสเต็มจะมีลักษณะดังนี้:
public class SystemRedirectService {

   public static void main(String arr[]) throws FileNotFoundException
   {
       PrintStream filePrintStream = new PrintStream(new File("C:\\Users\\Username\\Desktop\\test.txt"));
       /* Save the current value of System.out in a separate variable so that later
       we can switch back to console output */

       PrintStream console = System.out;
       // Assign a new value to System.out
       System.setOut(filePrintStream);
       System.out.println("This line will be written to the text file");

       // Restore the old value of System.out
       System.setOut(console);
       System.out.println("But this line will be output to the console!");
   }
}
ดังนั้น สตริงแรกจะถูกเขียนลงในไฟล์ข้อความ และสตริงที่สองจะแสดงในคอนโซล :) คุณสามารถคัดลอกโค้ดนี้ไปยัง IDE ของคุณและเรียกใช้ได้ เปิดไฟล์ข้อความแล้วคุณจะเห็นว่ามีการเขียนสตริงสำเร็จแล้ว :) ด้วยเหตุนี้บทเรียนของเราจึงสิ้นสุดลง วันนี้เรานึกถึงวิธีการทำงานกับสตรีมและผู้อ่าน เราจำได้ว่าทั้งสองอย่างนี้แตกต่างกันอย่างไร และได้เรียนรู้เกี่ยวกับความสามารถใหม่ๆ ของSystem.outที่เราใช้ในเกือบทุกบทเรียน :) จนกว่าจะถึงบทเรียนถัดไป!

อ่านเพิ่มเติม:

ความคิดเห็น
  • เป็นที่นิยม
  • ใหม่
  • เก่า
คุณต้องลงชื่อเข้าใช้เพื่อแสดงความคิดเห็น
หน้านี้ยังไม่มีความคิดเห็นใด ๆ