forked from I2P_Developers/i2p.i2p
Util: Use write-sync-close-rename for config file writing
This commit is contained in:
@ -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();
|
||||||
}
|
}
|
||||||
|
@ -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");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user