Save a user data file, as safely as we can. The basic algorithm is:
- We create a temporary file, in the same directory as the input file so we can safely rename it. Set it to with deleteOnExit(true);
- Our client writes the user data to this file. Data format or translation errors, if any, will be thrown during this process, leaving the user's original file intact. Client closes file.
- We delete the previous backup file, if one exists;
- We rename the user's previous file to filename.bak;
- We rename the temporary file to the save file.
This algorithm all but guarantees not to fail for reasons of disk full, permission denied, etc. Alternate algorithms could be employed that would preserve the original file ownership and permissions (e.g., on POSIX filesystems) but they can not then guarantee not to fail due to disk full conditions.
Step 1 is implemented in the constructor. Step 2 you do, by calling getWriter or getOutputStream (not both). Step 3, 4 and 5 are done in finish().
Normal usage is thus:
try { FileSaver saver = new FileSaver(file); final Writer writer = saver.getWriter(); PrintWriter out = new PrintWriter(writer); myWriteOutputFile(out); out.close(); saver.finish(); System.out.println("Saved OK"); } catch (IOException e) { System.out.println("Save FAILED"); }
Objects of this class may be re-used sequentially (for the same file) but are not thread-safe and should not be shared among different threads.
@author Extracted and updated by Ian Darwin from an olderapplication I wrote, prompted by discussion started by Brendon McLean on a private mailing list.