Java File atomic write

Description

Java File atomic write



//package com.demo2s;

import java.io.File;

import java.io.IOException;
import java.io.PrintWriter;
import java.math.BigInteger;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.security.SecureRandom;

public class Main {
    public static void main(String[] argv) throws Exception {
        String f = "";
        String input = "";
        atomicWrite(f, input);//from  w w  w  .j  a  va 2 s .c o m
    }

    /**
     * Write @input to the given file @f in an "atomic" manner. Meaning
     * that a reader, at any given moment, will read either the old or new contents, 
     * without getting half-written contents.
     * NOTE:
     * 1.    If a reader process keeps using the same file handler for @f (without closing and repoping it)
     *       it will always see the same contents at the time of creating the FH. 
     *       So, use with awareness and caution for both writer and readers.
     * 2.   IF the program gets killed ungracefully in the last 4 lines (from creating pw), we will probably end up with a temp file in the directory
     *       of @f. 
     * Implementation notes: The function uses POSIX atomic system command 'rename', which is supported in Ubuntu.
     * @param f : file path.
     * @param input : Data to write.
     * @throws IOException
     */
    public static void atomicWrite(String f, String input) throws IOException {
        File file = new File(f);
        String dir = file.getParent();

        // Generate a random string of size 32 for the tmp file.
        SecureRandom random = new SecureRandom();
        String tmp_name = new BigInteger(130, random).toString(32);
        String tmp_path = dir + "/" + tmp_name;

        PrintWriter pw = new PrintWriter(tmp_path);
        pw.write(input);
        pw.close();
        Files.move(Paths.get(tmp_path), Paths.get(f), StandardCopyOption.ATOMIC_MOVE);
    }
}



PreviousNext

Related