Java FileWriter overwrite

2019-07-20 10:51发布

I have a piece of code that generates new data whenever there is new data available as InputStream . The same file is overwritten everytime. Sometimes the file becomes 0 kb before it gets written. A webservice reads these files at regular intervals. I need to avoid the case when the file is 0 bytes.

How do it do this? Will locks help in this case? If the browser comes in to read a file which is locked, will the browser continue to show old data from the cache until the lock is released and file is available to be read again.

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();
}

4条回答
做自己的国王
2楼-- · 2019-07-20 11:19

Try writing to a temporary file (in the same file system) and once the file write is complete move it into place using File.renameTo(). If you underlying file system supports atomic move operations (most do) then you should get the behaviour that you require. If you are running on windows you will have to make sure you close the file after reading otherwise the file move will fail.

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();
       }
   }
}
查看更多
别忘想泡老子
3楼-- · 2019-07-20 11:23
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();
    }

this is not needed:

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

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

that's because work on the file is a method of class Data

查看更多
Emotional °昔
4楼-- · 2019-07-20 11:44
FileWriter fWriter = new FileWriter(fileName,true);

try using above :-)

查看更多
ら.Afraid
5楼-- · 2019-07-20 11:44

Your requirement is not very clear. Do you want to write a new name file every time or you want to append to the same file or you want to over write the same file? Anyway all three cases are easy and from the API you can manage it.

If the issue is that a web service is reading the file which is not yet complete i.e. is in writing phase. In your web service you should check if the file is read only, then only you read the file. In writing phase once writing is finished set the file to read only.

The 0Kb file happens because you are overwriting the same file again. Overwriting cleans up all the data and then start writing the new content.

查看更多
登录 后发表回答