2011-11-23 24 views

Trả lời

1

Giao diện trình đọc không không cho phép bạn quay lại, bạn chỉ có thể đọc. BufferedReader, mặt khác, tạo ra một bộ đệm, vì vậy bạn có thể trả về một chút khi đọc. Và đây là những gì các phương pháp cho.

Với phương thức mark() bạn đặt "điểm đánh dấu" vào vị trí, bạn có thể đọc tiếp. Khi bạn nhận ra bạn muốn trả lại vị trí đã đánh dấu, bạn sử dụng đặt lại() cho điều đó. Và từ thời điểm đó bạn đọc lại các giá trị tương tự. Bạn có thể sử dụng nó cho bất cứ điều gì bạn muốn.

1

Hãy tưởng tượng bạn có ký tự sau trong các BufferReader = "123456789", nếu bạn đánh dấu ở vị trí 4 so với '5' char sau đó thiết lập lại BufferReader của bạn, bạn sẽ kết thúc với 12345.

+1

Đây là một nửa câu trả lời, và những gì là thiết lập lại? – eeerahul

+0

Hey đã đưa ra một câu trả lời đúng. Đặt lại chỉ mang đến con trỏ, trỏ vào ký tự được đọc, đến vị trí mà nó đã được đánh dấu tại. –

13

Các markreset các phương pháp của luồng cung cấp cách nhảy ngược lại trong luồng và đọc lại dữ liệu.

Khi bạn gọi mark() trên BufferedReader, nó sẽ bắt đầu lưu dữ liệu bạn đọc từ thời điểm đó trở đi trong bộ đệm trong. Khi bạn gọi reset(), nó sẽ nhảy trở lại vị trí đã đánh dấu của luồng, do đó, read() s tiếp theo sẽ được bộ đệm trong bộ nhớ thỏa mãn. Khi bạn đọc qua phần cuối của bộ đệm đó, nó sẽ liên tục quay trở lại để đọc dữ liệu mới. BufferedInputStream hoạt động theo cùng một cách.

Tham số int thành mark cho biết số ký tự tối đa (cho BufferedReader) hoặc byte (cho BufferedInputStream) mà bạn muốn có thể quay lại. Nếu bạn đọc quá nhiều dữ liệu qua vị trí được đánh dấu, thì dấu có thể bị "vô hiệu" và gọi reset() sẽ không thành công với ngoại lệ.

Một ví dụ nhỏ:

BufferedReader r = new BufferedReader(new StringReader(
    "Happy Birthday to You!\n" + 
    "Happy Birthday, dear " + System.getProperty("user.name") + "!")); 
r.mark(1000); // save the data we are about to read 
System.out.println(r.readLine()); // read the first line 
r.reset(); // jump back to the marked position 
r.mark(1000); // start saving the data again 
System.out.println(r.readLine()); // read the first line again 
System.out.println(r.readLine()); // read the second line 
r.reset(); // jump back to the marked position 
System.out.println(r.readLine()); // read the first line one final time 

Trong ví dụ đó, tôi quấn StringReader trong một BufferedReader để có được phương pháp readLine(), nhưng StringReader s đã hỗ trợ markreset riêng của họ! Luồng đọc từ nguồn dữ liệu trong bộ nhớ thường hỗ trợ markreset chính chúng, vì chúng đã có tất cả dữ liệu trong bộ nhớ để chúng dễ đọc lại. Luồng đọc từ tệp hoặc đường ống hoặc ổ cắm mạng không tự nhiên hỗ trợ markreset, nhưng bạn luôn có thể thêm đối tượng địa lý đó vào bất kỳ luồng nào bằng cách gói nó trong một số BufferedInputStream hoặc BufferedReader.

+0

và thông số của nó là gì trong dấu()? – UnKnown

+0

@UnKnown Tôi đã mở rộng câu trả lời – Boann

8

mark() đánh dấu một điểm cụ thể trong luồng và reset() đặt lại luồng đó thành điểm gần đây nhất. Những phương pháp này cung cấp tính năng book-marking cho phép bạn đọc trước trong luồng để kiểm tra dữ liệu sắp tới.

Từ này documentation:

Các dấu() phương pháp đánh dấu một vị trí trong đầu vào dòng nước chảy có thể được "thiết lập lại" bởi gọi phương thức reset().Tham số readLimit là số ký tự có thể đọc được từ luồng sau khi đặt dấu trước dấu không hợp lệ. Ví dụ: nếu dấu() được gọi với giới hạn là đọc, thì khi 11 ký tự được đọc từ luồng trước khi phương thức reset() được gọi thì dấu không hợp lệ và đối tượng luồng là không bắt buộc phải nhớ nhãn hiệu. Lưu ý rằng số ký tự có thể được ghi nhớ bằng phương pháp này có thể là lớn hơn kích thước của bộ đệm đọc nội bộ. Nó cũng không phải là phụ thuộc vào luồng cấp dưới hỗ trợ chức năng đánh dấu/đặt lại .

+0

bạn cũng có thể chỉ sử dụng điều này để chỉ cần đánh dấu phần đầu và quay lại phần đầu để đọc lại bộ đệm? ví dụ nếu bạn muốn đọc một tệp hai lần. một lần để có được bối cảnh, quay trở lại đầu, sau đó đọc lại? – anon58192932

+0

và thông số của nó là gì? – UnKnown

6

Reader::mark(int readLimit) tài liệu nói:

Thiết lập một vị trí đánh dấu trong đầu đọc này. Tham số readLimit cho biết có thể đọc bao nhiêu ký tự trước khi dấu hiệu bị vô hiệu. Đặt lại cuộc gọi() sẽ định vị lại trình đọc trở lại vị trí đã đánh dấu nếu readLimit chưa được vượt qua.

Ví dụ:

import java.io.*; 
import static java.lang.System.out; 

public class App { 

    public static final String LINE = "Line 1\nLine 2\nLine 3\nLine 4\n"; 

    public static void main(String[] args) { 

     try (BufferedReader in = new BufferedReader(new StringReader(LINE))) { 

      // first check if this Reader support mark operation 
      if (in.markSupported()) { 

       out.println(in.readLine()); 
       in.mark(0);      // mark 'Line 2' 
       out.println(in.readLine()); 
       out.println(in.readLine()); 
       in.reset();      // reset 'Line 2' 
       out.println(in.readLine()); 
       in.reset();      // reset 'Line 2' 
       out.println(in.readLine()); 
       in.mark(0);      // mark 'Line 3' 
       out.println(in.readLine()); 
       in.reset();      // reset 'Line 3' 
       out.println(in.readLine()); 
       out.println(in.readLine()); 
      } 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
    } 
} 

Output:

Line 1 
Line 2 
Line 3 
Line 2 
Line 2 
Line 3 
Line 3 
Line 4 
+0

Làm thế nào bạn có thể gọi 'reset()'? Tôi nghĩ rằng nếu bạn 'mark()' với giới hạn đọc là 0, ngay sau khi một ký tự được đọc thì điểm đánh dấu trở thành không hợp lệ và không thể gọi lại được. Bạn có thể giải thích câu trả lời của bạn không? – snooze92

+0

@ snooze92 Chỉ cần chạy ví dụ này và cố gắng thay đổi đối số 'markLimit' trong phương thức' mark'. Bạn sẽ có kết quả tương tự mọi lúc. Cũng xem các ví dụ tương tự: [1] (http://goo.gl/KxU1Fy), [2] (http://goo.gl/S2R3qd). Tôi thực sự muốn đặt câu hỏi trên SO rằng ai đó đã cho tôi một lời giải thích về nó. –

+2

Sau khi chạy nhiều ví dụ của riêng tôi, tôi hiểu cơ chế 'mark (readAheadLimit)'/'reset()' tốt hơn một chút. Về cơ bản, phương thức 'mark' chỉ đánh dấu một điểm trong bộ đệm ** hiện tại, và' reset' cho phép bạn quay lại điểm đã đánh dấu đó. Vấn đề là, nó không có nghĩa là để đánh dấu một điểm trong một tập tin hoặc dòng, vì nó cần phải tăng kích thước bộ đệm để giữ cho khả năng truy cập vào điểm được đánh dấu. Đó là lý do tại sao một * * nên sử dụng một giới hạn tương đối nhỏ hơn kích thước bộ đệm. – snooze92

Các vấn đề liên quan