Util: Use write-sync-close-rename for config file writing

This commit is contained in:
zzz
2014-10-14 16:47:41 +00:00
parent 3331e1c152
commit be0cb84f97
2 changed files with 23 additions and 6 deletions

View File

@ -18,6 +18,7 @@ import java.io.ByteArrayOutputStream;
import java.io.EOFException; import java.io.EOFException;
import java.io.File; import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.InputStreamReader; import java.io.InputStreamReader;
@ -40,6 +41,7 @@ import java.util.zip.Deflater;
import net.i2p.I2PAppContext; import net.i2p.I2PAppContext;
import net.i2p.util.ByteCache; import net.i2p.util.ByteCache;
import net.i2p.util.FileUtil;
import net.i2p.util.OrderedProperties; import net.i2p.util.OrderedProperties;
import net.i2p.util.ReusableGZIPInputStream; import net.i2p.util.ReusableGZIPInputStream;
import net.i2p.util.ReusableGZIPOutputStream; import net.i2p.util.ReusableGZIPOutputStream;
@ -465,8 +467,10 @@ public class DataHelper {
public static void storeProps(Properties props, File file) throws IOException { public static void storeProps(Properties props, File file) throws IOException {
PrintWriter out = null; PrintWriter out = null;
IllegalArgumentException iae = null; IllegalArgumentException iae = null;
File tmpFile = new File(file.getPath() + ".tmp");
try { try {
out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(new SecureFileOutputStream(file), "UTF-8"))); FileOutputStream fos = new SecureFileOutputStream(tmpFile);
out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(fos, "UTF-8")));
out.println("# NOTE: This I2P config file must use UTF-8 encoding"); out.println("# NOTE: This I2P config file must use UTF-8 encoding");
for (Map.Entry<Object, Object> entry : props.entrySet()) { for (Map.Entry<Object, Object> entry : props.entrySet()) {
String name = (String) entry.getKey(); String name = (String) entry.getKey();
@ -491,6 +495,12 @@ public class DataHelper {
} }
out.println(name + "=" + val); out.println(name + "=" + val);
} }
out.flush();
fos.getFD().sync();
out.close();
out = null;
if (!FileUtil.rename(tmpFile, file))
throw new IOException("Failed rename from " + tmpFile + " to " + file);
} finally { } finally {
if (out != null) out.close(); if (out != null) out.close();
} }

View File

@ -480,10 +480,11 @@ public class FileUtil {
boolean success = false; boolean success = false;
boolean isWindows = SystemVersion.isWindows(); boolean isWindows = SystemVersion.isWindows();
// overwrite fails on windows // overwrite fails on windows
if (!isWindows) boolean exists = to.exists();
if (!isWindows || !exists)
success = from.renameTo(to); success = from.renameTo(to);
if (!success) { if (!success) {
to.delete(); if (exists && to.delete())
success = from.renameTo(to); success = from.renameTo(to);
if (!success) { if (!success) {
// hard way // hard way
@ -496,12 +497,12 @@ public class FileUtil {
} }
/** /**
* Usage: FileUtil (delete path | copy source dest | unzip path.zip) * Usage: FileUtil (delete path | copy source dest | rename from to | unzip path.zip)
* *
*/ */
public static void main(String args[]) { public static void main(String args[]) {
if ( (args == null) || (args.length < 2) ) { if ( (args == null) || (args.length < 2) ) {
System.err.println("Usage: delete path | copy source dest | unzip path.zip"); System.err.println("Usage: delete path | copy source dest | rename from to | unzip path.zip");
//testRmdir(); //testRmdir();
} else if ("delete".equals(args[0])) { } else if ("delete".equals(args[0])) {
boolean deleted = FileUtil.rmdir(args[1], false); boolean deleted = FileUtil.rmdir(args[1], false);
@ -523,6 +524,12 @@ public class FileUtil {
System.err.println("Unzipped [" + args[1] + "] to [" + to + "]"); System.err.println("Unzipped [" + args[1] + "] to [" + to + "]");
else else
System.err.println("Error unzipping [" + args[1] + "] to [" + to + "]"); System.err.println("Error unzipping [" + args[1] + "] to [" + to + "]");
} else if ("rename".equals(args[0])) {
boolean success = rename(new File(args[1]), new File(args[2]));
if (!success)
System.err.println("Error renaming [" + args[1] + "] to [" + args[2] + "]");
} else {
System.err.println("Usage: delete path | copy source dest | rename from to | unzip path.zip");
} }
} }