2015-07-31 11 views
5

Sau khi chơi với PrintWriter và các tập tin, tôi có một nghi ngờ về lý do tại sao làm đôi khi tôi đọc tác phẩm của tôi ngay khi tôi tạo ra chúng, có những mâu thuẫn, ví dụ:Khi nào PrintWriter tự động in ra tệp?

File file = new File("Items.txt"); 
int loopValue = 10; 
try { 
    PrintWriter fout = new PrintWriter(file); 
    for (int i = 0; i < loopValue; i++) { 
     fout.print(i + " asdsadas" + System.lineSeparator()); 
    } 
    //fout.flush(); <-- I know if I call flush or close this problem don't occur 
    //fout.close(); 

    System.out.println("Here is the file:"); 
    Scanner readFile = new Scanner(file); 
    while (readFile.hasNext()) { 
     System.out.println(readFile.nextLine()); 
    } 
} catch (FileNotFoundException e) { 
    System.err.println(e.getMessage()); 
} 

Nếu tôi chạy mã này, tôi sẽ đọc trong giao diện điều khiển một tập tin rỗng, một cái gì đó như thế này:

Here is the file: 

Nhưng nếu tôi thay đổi loopValue một cái gì đó giống như 10000, tôi sẽ có một cái gì đó như thế này:

Here is the file: 
0 asdsadas 
1 asdsadas 
2 asdsadas 
... 
... continues 
... 
9356 asdsadas 
9357 asdsadas 
9358 <--- here ends, note that it doesnt end in the value 9999 

Tôi biết rằng nếu tôi gọi flush() hoặc close() trước khi đọc tệp, tôi có thể loại bỏ vấn đề này, nhưng tại sao điều này lại xảy ra? Khi nào thì PrintWriter quyết định đó là thời gian để làm sạch bộ đệm của nó mà tôi không biết khi nào? và tại sao khi tôi đóng hoặc tuôn ra PrintWriter vấn đề này sẽ không xảy ra?

Cảm ơn!

+0

Vui lòng xem lại các câu trả lời được đưa ra bên dưới. –

Trả lời

3

Khái niệm chung và động lực đằng sau bộ đệm cho PrintWriter là tốn kém để viết một cái gì đó ra bàn điều khiển. Do đó, bằng cách xếp hàng các thay đổi đang chờ xử lý để xuất, chương trình có thể chạy hiệu quả hơn. Hãy tưởng tượng bạn đã có một chương trình Java đang làm một cái gì đó rất chuyên sâu từ một quan điểm CPU, chẳng hạn như tính toán nặng trong một ứng dụng đa luồng. Sau đó, nếu bạn là cũng nhấn mạnh rằng mỗi cuộc gọi đến PrintWriter.print() sẽ cung cấp kết quả ngay lập tức, chương trình có thể bị treo và hiệu suất tổng thể sẽ giảm.

Nếu bạn nhấn mạnh xem kết quả từ PrintWriter ngay sau cuộc gọi, bạn có thể gọi flush() để thực hiện việc này. Nhưng như đã đề cập, có thể có một hình phạt hiệu suất trong những điều kiện nhất định.

1

Đệm là một kỹ thuật cơ bản và quan trọng để tăng tốc I/O

Khi bạn gọi close nó sẽ giải phóng tất cả các tài nguyên hệ thống liên kết với nó đây tập tin sẽ được sử dụng bởi Printwriter và chưa được lưu của bạn thay đổi cho đến khi bạn tuôn ra nó. Vì vậy, Scanner đang cố gắng đọc tệp sẽ nhận được nội dung không thay đổi cũ.Bây giờ khi bạn gọi flush nó chỉ xóa tệp và buộc người viết ghi tất cả bộ đệm bytes cho đến khi luồng phát trực tiếp bộ đệm của bạn và ghi vào tệp. bạn nên sử dụng finally chặn thành close luồng và lưu ý rằng close() theo mặc định tuôn ra luồng cho bạn nhưng tại đây bạn muốn sử dụng nó theo dòng bạn nên sử dụng tuôn ra tốt hơn và đóng nó trong khối finally.

1

Từ câu hỏi của bạn, tôi lấy nó là bạn đã biết rằng có (hoặc ít nhất có thể) một bộ đệm liên quan được rửa sạch trên flush và trên close.

Như để khi xả nước xảy ra tự động, JavaDoc on PrintWriter nói:

Không giống như các lớp PrintStream, nếu tự động xả được kích hoạt nó sẽ được thực hiện chỉ khi một trong những phương pháp println, printf, hoặc định dạng được gọi, thay vì bất cứ khi nào một ký tự dòng mới xảy ra là đầu ra.

Bây giờ, cách thức và nếu xảy ra đệm phụ thuộc vào OutputStream bên dưới được sử dụng (có thể được chỉ định thông qua hàm tạo). Nếu bạn sử dụng BufferedOutputStream, bạn có thể chỉ định kích thước của bộ đệm. Mặc dù nó không được đề cập một cách rõ ràng trong các tài liệu, việc xả cũng xảy ra khi bộ đệm đầy.

Các PrintWriter constructor taking a File mà bạn đang sử dụng trong ví dụ của bạn nói

Tạo một PrintWriter mới, mà không cần xả dòng tự động, với một file nào đó. Hàm tạo thuận tiện này tạo ra OutputStreamWriter trung gian cần thiết, sẽ mã hóa các ký tự bằng cách sử dụng bộ ký tự mặc định cho cá thể của máy ảo Java này.

mà không thực hiện bất kỳ đảm bảo bổ sung nào về những gì OutputStreamWriter nó sẽ tạo và cài đặt nào sẽ sử dụng.

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