CodeGym /Blog Java /Ngẫu nhiên /Thực hành làm việc với các lớp BuffredReader và InputStre...

Thực hành làm việc với các lớp BuffredReader và InputStreamReader

Xuất bản trong nhóm
CHÀO! Bài học hôm nay sẽ được chia thành hai phần để tiện theo dõi. Chúng tôi sẽ lặp lại một số chủ đề cũ mà chúng tôi đã đề cập trước đó và chúng tôi sẽ xem xét một số tính năng mới :) Hãy bắt đầu với chủ đề đầu tiên. Bạn đã có một lớp học như BufferedReadernhiều lần. Tôi hy vọng bạn không có thời gian để quên câu nói này:

BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
Trước khi đọc thêm, hãy cố gắng nhớ từng thành phần — System.in, InputStreamReader, BufferedReader— chịu trách nhiệm về cái gì và tại sao nó lại cần thiết. Bạn có nhớ? Nếu không, không phải lo lắng. :) Nếu bạn quên điều gì đó, hãy đọc lại bài học này dành riêng cho các lớp đọc. Chúng tôi sẽ nhớ lại ngắn gọn những gì mỗi người trong số họ có thể làm. System.in— đây là luồng nhận dữ liệu từ bàn phím.  Về nguyên tắc, chỉ riêng nó là đủ để thực hiện logic cần thiết để đọc văn bản. Nhưng, như bạn sẽ nhớ lại, System.inchỉ có thể đọc byte, không phải 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 thực thi mã này và nhập ký tự Cyrillic "Й", đầu ra sẽ là:

Й
208
153
10 
Các ký tự Cyrillic chiếm 2 byte trong bộ nhớ và chúng được hiển thị trên màn hình. Số 10 là biểu diễn thập phân của ký tự xuống dòng, tức là từ khi nhấn Enter. Đọc byte là một niềm vui, vì vậy việc sử dụng System.inkhông thuận tiện lắm. Để đọc chính xác các chữ cái Cyrillic (và các chữ cái khá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); 
       } 
   } 
} 
Chúng tôi nhập cùng một chữ cái "Й", nhưng kết quả lần này khác:

Й 
1049 
10
InputStreamReaderđã chuyển đổi hai byte (208 và 153) thành một số duy nhất 1049. Đây là ý nghĩa của việc đọc các ký tự. 1049 tương ứng với chữ cái Cyrillic "Й". Chúng ta có thể dễ dàng thuyết phục bản thân rằng điều này là đúng:

public class Main { 

   public static void main(String[] args) throws IOException { 
       char x = 1049; 
       System.out.println(x); 
   } 
} 
Đầu ra bảng điều khiển:

Й
Và như forBufferedReader(và nói chung, BufferedAnythingYouWant), 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 web) khá tốn kém về hiệu suất. Do đó, để giảm số lần truy cập, BufferedReaderhãy đọc và tích lũy dữ liệu trong một bộ đệm đặc biệt và chúng tôi lấy dữ liệu từ đó. Do đó, số lần nguồn dữ liệu được truy cập bị cắt giảm — có thể theo một số bậc độ lớn! Một trong BufferedReadernhững tính năng khác của 's và lợi thế của nó so với thông thường' InputStreamReader, là readLine()phương pháp cực kỳ hữu ích, đọc toàn bộ dòng dữ liệu chứ không phải các số riêng lẻ. Tất nhiên, điều này cực kỳ tiện lợi khi xử lý các văn bản lớn. Đây là những dòng đọc trông 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 ("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
Thực hành làm việc với lớp BuffredReader và InputStreamReader - 2Tất nhiên, BufferedReaderlà rất linh hoạt. Bạn không bị giới hạn khi làm việc với bàn phím. Ví dụ: bạn có thể đọc dữ liệu trực tiếp từ web, chỉ 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 tệp:

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à chúng ta chưa từng chạm tới trước đây. Như bạn chắc chắn còn nhớ, Systemlớp có hai trường tĩnh — System.invà  System.out. Những anh em sinh đôi này là các đối tượng truyền phát. System.inlà một InputStream. Và System.out là một PrintStream. Ngay bây giờ, chúng ta sẽ nói về  System.out. Nếu chúng ta xem Systemmã nguồn của lớp, chúng ta sẽ thấy điều này:

public final class System { 
……………... 
public final static PrintStream out = null; 
 ………… 
} 
Do đó,  System.out  chỉ đơn giản là một biến tĩnh thông thường củaSystem lớp. Không có gì kỳ diệu về nó :) outBiến là một PrintStreamtham chiếu. Đây là một câu hỏi thú vị: Khi System.out.println()được thực thi, tại sao chính xác đầu ra lại chuyển đến bàn điều khiển mà không phải ở nơi nào khác? Và điều này có thể được thay đổi bằng cách nào đó? Ví dụ: giả sử chúng tôi muốn đọc dữ liệu từ bàn điều khiển và ghi dữ liệu đó vào tệp văn bản. Có thể bằng cách nào đó thực hiện điều này đơn giản bằng cách sử dụng  System.outthay vì các lớp người đọc và người viết bổ sung không? Thật vậy, nó là :) Và chúng ta có thể làm điều đó mặc dù System.outbiến được đánh dấu bằng finalcông cụ sửa đổi!  Thực hành làm việc với lớp BuffredReader và InputStreamReader - 3Vì vậy, những gì chúng ta cần để làm cho điều này xảy ra? Trước hết, chúng ta cần một PrintStreamđối tượng mới để thay thế đối tượng hiện tại. Đối tượng hiện tại, được đặt trongSystemclass theo mặc định, không phục vụ mục đích của chúng tôi: nó trỏ đến bảng điều khiển. Bạn cần tạo một tệp mới trỏ đến tệp văn bản — "đích" cho dữ liệu của chúng tôi. Thứ hai, chúng ta cần hiểu cách gán giá trị mới cho System.outbiến. Bạn không thể sử dụng toán tử gán đơn giản vì biến được đánh dấu final. Hãy làm việc ngược lại từ cuối. Khi điều đó xảy ra, Systemlớp có phương thức chúng ta cần: setOut(). Nó lấy một PrintStreamđối tượng và đặt nó làm đích cho đầu ra. Đó chỉ là những gì chúng ta cần! Tất cả những gì còn lại là tạo một PrintStreamđối tượng. Điều này cũng dễ dàng:

PrintStream filePrintStream = new PrintStream(new File("C:\\Users\\Username\\Desktop\\test.txt"));
Mã đầy đủ 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"));
       /* 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!"); 
   } 
}
Do đó, chuỗi đầu tiên được ghi vào tệp văn bản và chuỗi thứ hai được hiển thị trong 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ó. Mở tệp văn bản và bạn sẽ thấy rằng chuỗi đã được viết thành công ở đó :) Đến đây, bài học của chúng ta đã kết thúc. Hôm nay chúng tôi nhắc lại cách làm việc với luồng và người đọc. Chúng tôi nhớ lại chúng khác nhau như thế nào và tìm hiểu về một số khả năng mới của System.out, mà chúng tôi đã sử dụng trong hầu hết các bài học :) Cho đến các bài học tiếp theo!
Bình luận
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION