2009-10-24 122 views
2

我有一段代碼,只要有新的數據可用作InputStream,就會生成新的數據。每次都會覆蓋同一個文件。有時文件在寫入之前變爲0 kb。 webservice會定期讀取這些文件。當文件爲0字節時,我需要避免這種情況。Java FileWriter覆蓋

它是如何做到這一點的?在這種情況下鎖會有幫助嗎?如果瀏覽器進入讀取被鎖定的文件,瀏覽器是否會繼續顯示緩存中的舊數據,直到鎖被釋放並且文件可以再次被讀取。

try{ 
String outputFile = "output.html";  
FileWriter fWriter = new FileWriter(outputFile); 
//write the data ... 

fWriter .flush(); 


outputFile = "anotheroutput.html";  
fWriter = new FileWriter(outputFile); 
//write the data ... 

fWriter .flush(); 
fWriter.close(); 
} 
catch(Exception e) 
{ 
e.prinStackTrace(); 
} 
+0

我認爲你正在尋找'File.length()'。此方法返回以字節爲單位的文件大小。 – 2009-10-24 05:29:14

回答

0
public class Data 
{ 
    String fileName; 
    protected Data(String fileName) 
    { 
    this.fileName= fileName; 
    return; // return from constructor often not needed. 
    } 

    /* above is in some class somehwere 
    * then your code brings new info to the file 
    */ 

    // 
    public synchronized accessFile(String data) 
    { 
    try 
    { 
     // File name to be class member. 
     FileWriter fWriter = new FileWriter(fileName); 
     //write the data ... 
     fWriter.write(data); 
     fWriter .flush(); 
     fWriter .close(); 
     return; 
    } 
    catch(Exception e) 
    { 
     e.prinStackTrace(); 
    } 

這是沒有必要:

outputFile = "anotheroutput.html";  
fWriter = new FileWriter(outputFile); 
//write the data ... 

fWriter .flush(); 
fWriter.close(); 

這是因爲在檔案工作是一流的數據

+0

!?您假設所有訪問該文件的程序都在同一個JVM中,以便「synchronized」關鍵字可以防止同時使用該文件的多個例程。關於JVM之外的進程呢?電腦外? (如果一個文件是通過網絡共享的) – 2009-10-24 02:54:07

+0

傑森,我試圖找到一些東西,讓我想起扁平化(我不知道它叫什麼,我一直這樣做)的概念,在哪裏分類代碼通過填充複製粘貼緩衝區並展開循環,我會在op注意到它之後進入sync()和鎖定狀態 - 此刻我正忙於JCE,在獲得零長度時一直保持運行狀態做的問題工作......這是另一個像你提到我的...嘿,網站所有者 - >我們可以得到一個代碼編輯器在所有沉重的腳本??? .....真的,真的會幫助(大時間 ! ) – 2009-10-24 03:16:17

0

您的需求的方法還不是很清楚。你想每次寫一個新的名字文件,或者你想追加到同一個文件,或者你想要寫同一個文件嗎?無論如何,所有這三種情況都很簡單,您可以從API中進行管理。

如果問題是Web服務正在讀取尚未完成的文件,即處於寫入階段。在你的Web服務中,你應該檢查文件是否只讀,然後只讀你的文件。一旦寫入完成,在寫入階段將文件設置爲只讀。

發生0Kb文件是因爲您再次覆蓋同一個文件。覆蓋清理所有的數據,然後開始編寫新的內容。

2

嘗試寫入臨時文件(在同一個文件系統中),並且文件寫入完成後,使用File.renameTo()將其移入到位。如果你的底層文件系統支持原子移動操作(大部分都是這樣),那麼你應該得到你需要的行爲。如果您在Windows上運行,則必須確保在閱讀完文件後關閉文件,否則文件移動將失敗。

public class Data 
{ 
    private final File file; 
    protected Data(String fileName) { 
     this.file = new File(filename); 
    } 

    /* above is in some class somehwere 
    * then your code brings new info to the file 
    */ 

    // 
    public synchronized accessFile(String data) { 
     try { 
      // Create temporary file 
      String tempFilename = UUID.randomUUID().toString() + ".tmp"; 
      File tempFile = new File(tempFilename); 

      //write the data ... 
      FileWriter fWriter = new FileWriter(tempFile); 
      fWriter.write(data); 
      fWriter.flush(); 
      fWriter.close(); 

      // Move the new file in place 
      if (!tempFile.renameTo(file)) { 
       // You may want to retry if move fails? 
       throw new IOException("Move Failed"); 
      } 
     } catch(Exception e) { 
      // Do something sensible with the exception. 
      e.prinStackTrace(); 
     } 
    } 
} 
1
FileWriter fWriter = new FileWriter(fileName,true); 

嘗試使用上面:-)