2012-08-16 38 views
6

Vì lý do nào đó mã này dẫn đến tệp text.txt bị cắt ngắn. Nó nên (theo tôi) viết ra 1000 kết quả, nhưng tập tin đầu ra có số lượng khác nhau của dòng (tùy thuộc vào chạy). Thật kỳ lạ, việc ghi vào tập tin dừng lại ở giữa lệnh viết, sao cho một dòng có thể không hoàn thành. Hiện tại, ba dòng cuối cùng của tệp văn bản cho lần chạy mới nhất như sau:Bufferedwriter dừng ở giữa văn bản

749, 78.97988, 97.80454, 99.6625, 94.00000015258789 
750, 4.1745043, 86.64212, 107.59311, 71.00000008583069 
751, 

và thế là xong. Không có gì khác sau đó.

Đây là mã:

import java.io.BufferedWriter; 
import java.io.FileWriter; 
import java.io.IOException; 
import java.io.Writer; 
import java.util.Random; 

public class ColorGrayScale { 

/** 
* @param args 
* @throws IOException 
*/ 
@SuppressWarnings("resource") 
public static void main(String[] args) throws IOException { 
    // TODO Auto-generated method stub 
    Writer out = new BufferedWriter(new FileWriter("test.txt"),16*1024); 
    Random generator = new Random(); 
    float red = 0, green = 0, blue = 0; 
    int i = 0; 

    while (i<1000) { 

     float grey = generator.nextInt(127) + 64; 
     int sequence = generator.nextInt(6) + 1; // to pick from 1 of six 
                // orders 
     switch (sequence) { // the various orders that red green and blue 
          // are going to be in 
     case 1: 
      red = (float) (generator.nextFloat() * (grey/.21)); 
      green = (float) (generator.nextFloat() * ((grey - (red * .21))/.71)); 
      blue = (float) ((grey - (red * .21) - (green * .71))/0.08); 
      break; 
     case 2: 
      red = (float) (generator.nextFloat() * (grey/.21)); 
      blue = (float) (generator.nextFloat() * ((grey - (red * .21))/.08)); 
      green = (float) ((grey - (red * .21) - (blue * .08))/0.71); 
      break; 
     case 3: 
      green = (float) (generator.nextFloat() * (grey/.71)); 
      red = (float) (generator.nextFloat() * ((grey - (green * .71))/.21)); 
      blue = (float) ((grey - (red * .21) - (green * .71))/.08); 
      break; 
     case 4: 
      green = (float) (generator.nextFloat() * (grey/.71)); 
      blue = (float) (generator.nextFloat() * ((grey - (green * .71))/.08)); 
      red = (float) ((grey - (green * .71) - (blue * .08))/.21); 
      break; 
     case 5: 
      blue = (float) (generator.nextFloat() * (grey/.08)); 
      red = (float) (generator.nextFloat() * ((grey - (blue * .08))/.21)); 
      green = (float) ((grey - (blue * .08) - (red * .21))/.71); 
      break; 
     case 6: 
      blue = (float) (generator.nextFloat() * (grey/.08)); 
      green = (float) (generator.nextFloat() * ((grey - (blue * .08))/.71)); 
      red = (float) ((grey - (blue * .08) - (green * .71))/.21); 
      break; 
     } 
     if (red < 256 && blue < 256 && green < 256) { 
      out.write("" + i + ", " + red + ", " + green + ", " + blue 
        + ", " + (.21 * red + .71 * green + 0.08 * blue + "\n")); 
      i++; 
     } 
    } 
} 

}

+1

Tôi nghĩ bạn nên đảm bảo 'close()' được gọi trên đối tượng 'out'. –

Trả lời

16

Bạn quên đóng() người viết, vì vậy bạn không bao giờ cho nó cơ hội để xóa đầu ra đệm vào đĩa.

+0

Có nó! Cám ơn rất nhiều! – user1602004

2

Bạn nên cân nhắc flushing luồng của mình sau mỗi lần ghi. Hãy thử một cái gì đó như thế này:

try{ 
    //your code 
    out.write("" + i + ", " + red + ", " + green + ", " + blue 
      + ", " + (.21 * red + .71 * green + 0.08 * blue + "\n")); 
    i++; 
}finally{ 
    //Close the stream 
    out.close(); 
} 

Ngoài ra, bạn nên đảm bảo rằng bạn đóng luồng khi kết thúc hoạt động của mình. Một cách hay để cấu trúc chương trình của bạn có thể là:

Random generator = new Random(); 
float red = 0, green = 0, blue = 0; 
int i = 0; 

Writer out = null; 

try{ 
    out = new BufferedWriter(new FileWriter("test.txt"), 16 * 1024); 

    while (i < 1000) { 
     //your logic 
     if (red < 256 && blue < 256 && green < 256) { 
       out.write("" + i + ", " + red + ", " + green + ", " + blue 
         + ", " + (.21 * red + .71 * green + 0.08 * blue + "\n")); 
       i++; 
     } 
    } 
}finally{ 
    if(out != null){ 
     out.close(); 
    } 
} 
+2

Tại sao tuôn ra sau mỗi lần lặp? Điều đó không hiệu quả sao? Có lẽ, kích thước bộ đệm có thể được thiết lập một cách rõ ràng để cho người viết quyết định khi nào tuôn ra, nếu kích thước bộ đệm mặc định không phải là kích thước mong muốn. – Vikdor

+0

@Vikdor - Tôi đồng ý. Nó không hiệu quả. Đã cập nhật câu trả lời của tôi! Cảm ơn bạn đã chỉ ra điều đó :) – Sujay

+2

Gọi 'flush()' ngay trước khi 'close()' trên các nhà văn tiêu chuẩn và OutputStream trong gói java.io là thừa. Tất cả đều đảm bảo chúng tuôn ra đầu ra của chúng khi bạn gọi 'close()'. –

2

Hai thứ.

  1. Flush dòng
  2. Đóng stream

Hãy thử một cái gì đó như:

Writer out = null; 
try { 
    out = new BufferedWriter(new FileWriter("test.txt"),16*1024); 

    // Write some stuff 

    out.flush(); 
} finally { 
    try { 
     out.close(); 
    } catch (Exception exp) { 
    } 
} 

Hãy thử và ghi nhớ, đó là một "đệm". Điều đó có nghĩa rằng nó giữ các công cụ được lưu trữ trong bộ nhớ cho đến khi nó quyết định nó cần phải được viết hoặc yêu cầu của bạn một cách rõ ràng để "tuôn ra" nội dung của nó.

Ngoài ra, bạn nên luôn luôn close luồng của mình. Điều này ngăn các vấn đề về tệp có thể bị khóa và các sự cố xử lý tệp: P

+1

Không cần phải 'flush()' luồng trừ khi có điều gì khác muốn bắt đầu đọc nó trước khi bạn viết xong hoặc có khả năng 'close()' sẽ không bao giờ được gọi. –

+0

@AdrianPronk Tôi chỉ hoang tưởng: D – MadProgrammer