JavaRush /Blog Java /Random-VI /Thực hành làm việc với lớp BufferedReader và inputStreamR...

Thực hành làm việc với lớp BufferedReader và inputStreamReader

Xuất bản trong nhóm
Xin chào! Bài giảng hôm nay sẽ được chia thành hai phần. Chúng tôi sẽ lặp lại một số chủ đề cũ mà chúng tôi đã đề cập trước đây và xem xét một số tính năng mới :) Thực hành làm việc với lớp BufferedReader và inputStreamReader - 1Hãy bắt đầu với chủ đề đầu tiên. Sự lặp lại là mẹ của việc học :) Bạn đã sử dụng một lớp như BufferedReader. Tôi hy vọng bạn chưa quên lệnh này:
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
Trước khi đọc tiếp, hãy cố gắng nhớ xem mỗi thành phần ( System.in, InputStreamReader, BufferedReader) chịu trách nhiệm gì và chúng cần thiết để làm gì. Đã xảy ra? Nếu không, đừng lo lắng :) Nếu đến thời điểm này bạn đã quên điều gì đó, hãy đọc lại bài giảng dành riêng cho độc giả này một lần nữa. Chúng ta hãy nhớ ngắn gọn những gì mỗi người trong số họ có thể làm. System.inlà thread nhận dữ liệu từ bàn phím. Về nguyên tắc, để thực hiện logic đọc văn bản, chúng ta chỉ cần một cái là đủ. Tuy nhiên, như bạn nhớ, System.innó chỉ có thể đọc byte chứ không thể đọc ký tự:
public class Main {

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

       while (true) {
           int x = System.in.read();
           System.out.println(x);
       }
   }
}
Nếu chúng ta chạy mã này và nhập chữ "Y" vào bảng điều khiển, kết quả sẽ như thế này:

Й
208
153
10
Ký tự Cyrillic chiếm 2 byte trong bộ nhớ, được hiển thị trên màn hình (và số 10 là byte biểu thị ngắt dòng, tức là nhấn Enter). Đọc byte là một điều thú vị, vì vậy việc sử dụng nó System.inở dạng thuần túy sẽ bất tiện. Để đọc các chữ cái Cyrillic (và không chỉ) mà mọi người đều có thể hiểu được, chúng tôi sử dụng InputStreamReaderlàm trình bao bọc:
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);
       }
   }
}
Nếu chúng ta nhập cùng một chữ cái “Y” vào bảng điều khiển, kết quả lần này sẽ khác:

Й
1049
10
InputStreamReaderđã chuyển đổi hai byte đã đọc (208, 153) thành một số duy nhất 1049. Đây là cách đọc theo ký tự. 1049 tương ứng với chữ “Y”, có thể dễ dàng xác minh:
public class Main {

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

       char x = 1049;
       System.out.println(x);
   }
}
Đầu ra của bảng điều khiển:

Й
Vâng, đối với BufferedReader'a (và nói chung - BufferedAnything), các lớp đệm được sử dụng để tối ưu hóa hiệu suất. Truy cập nguồn dữ liệu (tệp, bảng điều khiển, tài nguyên trên Internet) là một hoạt động khá tốn kém về mặt hiệu suất. Do đó, để giảm số lượng các cuộc gọi như vậy, BufferedReadernó sẽ đọc và tích lũy dữ liệu trong một bộ đệm đặc biệt, từ đó chúng ta có thể nhận được dữ liệu sau này. Kết quả là số lượng cuộc gọi đến nguồn dữ liệu giảm đi vài lần, thậm chí hàng chục lần! Một tính năng bổ sung khác của BufferedReader'a và ưu điểm của nó so với thông thường InputStreamReader' là phương pháp cực kỳ hữu ích readLine()giúp đọc dữ liệu dưới dạng toàn bộ chuỗi thay vì dưới dạng số riêng lẻ. Tất nhiên, điều này làm tăng thêm sự tiện lợi khi triển khai, chẳng hạn như văn bản lớn. Đây là cách đọc một dòng sẽ như thế nào:
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("Пользователь ввел следующий текст:");
       System.out.println(s);
       reader.close();
   }
}

BufferedReader+InputStreamReader работает быстрее, чем просто InputStreamReader
Пользователь ввел следующий текст:
BufferedReader+InputStreamReader работает быстрее, чем просто InputStreamReader
Thực hành làm việc với lớp BufferedReader và inputStreamReader - 2Tất nhiên, BufferedReaderđây là một cơ chế rất linh hoạt và cho phép bạn làm việc không chỉ với bàn phím. Ví dụ: bạn có thể đọc dữ liệu trực tiếp từ Internet bằng cách chuyển URL được yêu cầu tới trình đọc:
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();
   }
}
Bạn có thể đọc dữ liệu từ một tệp bằng cách chuyển đường dẫn đến nó:
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();
   }
}

Thay thế System.out

Bây giờ chúng ta hãy xem xét một khả năng thú vị mà trước đây chúng ta chưa từng đề cập tới. Có thể bạn còn nhớ, Systemcó hai trường tĩnh trong lớp - System.inSystem.out. Hai anh em sinh đôi này là các đối tượng của lớp thread. System.in- lớp trừu InputStreamtượng Một System.outlớp học PrintStream. Bây giờ chúng ta sẽ nói cụ thể về System.out. Nếu đi vào mã nguồn của lớp Systemchúng ta sẽ thấy thế này:
public final class System {

……………...

public final static PrintStream out = null;

  …………

}
Vì vậy, System.outchỉ là một biến lớp tĩnh thông thườngSystem . Không có phép thuật nào trong đó :) Biến outthuộc về lớp PrintStream. Đây là một câu hỏi thú vị: tại sao khi thực thi mã, System.out.println()kết quả đầu ra lại xuất hiện trong bảng điều khiển mà không phải ở nơi nào khác? Và có thể thay đổi điều này bằng cách nào đó? Ví dụ: chúng tôi muốn đọc dữ liệu từ bảng điều khiển và ghi nó vào tệp văn bản. Có thể bằng cách nào đó triển khai logic như vậy mà không cần sử dụng các lớp trình đọc và trình ghi bổ sung mà chỉ cần sử dụng System.out? Vẫn có thể :) Và mặc dù biến System.outđược chỉ định bởi một modifier final, chúng ta vẫn có thể làm được! Thực hành làm việc với lớp BufferedReader và inputStreamReader - 3Vậy chúng ta cần gì cho việc này? Đầu tiên , chúng ta cần một đối tượng lớp mới PrintStreamthay vì đối tượng hiện tại. Đối tượng hiện tại được cài đặt trong lớp Systemtheo mặc định không phù hợp với chúng ta: nó trỏ đến bàn điều khiển. Chúng ta cần tạo một tệp mới sẽ trỏ đến tệp văn bản làm “đích” cho dữ liệu của chúng ta. Thứ hai , bạn cần hiểu cách gán một giá trị mới cho một biến System.out. Bạn không thể làm như vậy được vì nó được đánh dấu final. Hãy bắt đầu từ cuối. Lớp này Systemchứa chính xác phương thức chúng ta cần - setOut(). Nó lấy một đối tượng làm đầu vào PrintStreamvà đặt nó làm điểm đầu ra. Đúng thứ chúng ta cần! Tất cả những gì còn lại là tạo đối tượng PrintStream. Việc này cũng dễ thực hiện:
PrintStream filePrintStream = new PrintStream(new File("C:\\Users\\Username\\Desktop\\test.txt"));
Toàn bộ mã sẽ trông như thế này:
public class SystemRedirectService {

   public static void main(String arr[]) throws FileNotFoundException
   {
       PrintStream filePrintStream = new PrintStream(new File("C:\\Users\\Username\\Desktop\\test.txt"));

       /*Сохраним текущее meaning System.out в отдельную переменную, чтобы потом
       можно было переключиться обратно на вывод в консоль*/
       PrintStream console = System.out;

       // Присваиваем System.out новое meaning
       System.setOut(filePrintStream);
       System.out.println("Эта строка будет записана в текстовый файл");

       // Возвращаем System.out старое meaning
       System.setOut(console);
       System.out.println("А эта строка - в консоль!");
   }
}
Kết quả là dòng đầu tiên sẽ được ghi vào tệp văn bản và dòng thứ hai sẽ được xuất ra bảng điều khiển :) Bạn có thể sao chép mã này vào IDE của mình và chạy nó. Bằng cách mở tệp văn bản, bạn sẽ thấy dòng yêu cầu đã được viết thành công ở đó :) Bài giảng kết thúc. Hôm nay chúng ta đã nhớ cách làm việc với các luồng và trình đọc, nhớ lại chúng khác nhau như thế nào và tìm hiểu về các tính năng mới System.outmà chúng ta đã sử dụng trong hầu hết mọi bài học :) Hẹn gặp lại các bạn trong các bài giảng tiếp theo!
Bình luận
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION