Safely save config

This commit is contained in:
Glavo 2021-12-13 16:10:05 +08:00 committed by Yuhui Huang
parent 94e32694b2
commit e48bf012a6
2 changed files with 23 additions and 4 deletions

View File

@ -30,7 +30,6 @@ import java.nio.file.*;
import java.util.Map;
import java.util.logging.Level;
import static java.nio.charset.StandardCharsets.UTF_8;
import static org.jackhuang.hmcl.util.Logging.LOG;
public final class ConfigHolder {
@ -175,7 +174,7 @@ public final class ConfigHolder {
private static void writeToConfig(String content) throws IOException {
LOG.info("Saving config");
synchronized (configLocation) {
Files.write(configLocation, content.getBytes(UTF_8));
FileUtils.saveSafely(configLocation, content);
}
}
@ -219,7 +218,7 @@ public final class ConfigHolder {
private static void writeToGlobalConfig(String content) throws IOException {
LOG.info("Saving global config");
synchronized (GLOBAL_CONFIG_PATH) {
Files.write(GLOBAL_CONFIG_PATH, content.getBytes(UTF_8));
FileUtils.saveSafely(GLOBAL_CONFIG_PATH, content);
}
}

View File

@ -20,6 +20,7 @@ package org.jackhuang.hmcl.util.io;
import org.jackhuang.hmcl.util.Lang;
import org.jackhuang.hmcl.util.StringUtils;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
@ -36,7 +37,6 @@ import java.util.function.Predicate;
import static java.nio.charset.StandardCharsets.UTF_8;
/**
*
* @author huang
*/
public final class FileUtils {
@ -425,4 +425,24 @@ public final class FileUtils {
return Optional.empty();
}
}
public static Path tmpSaveFile(Path file) {
return file.toAbsolutePath().resolveSibling("." + file.getFileName().toString() + ".tmp");
}
public static void saveSafely(Path file, String content) throws IOException {
Path tmpFile = tmpSaveFile(file);
try (BufferedWriter writer = Files.newBufferedWriter(tmpFile, StandardOpenOption.TRUNCATE_EXISTING, StandardOpenOption.CREATE)) {
writer.write(content);
}
try {
if (Files.exists(file) && Files.getAttribute(file, "dos:hidden") == Boolean.TRUE) {
Files.setAttribute(tmpFile, "dos:hidden", true);
}
} catch (Throwable ignored) {
}
Files.move(tmpFile, file, StandardCopyOption.REPLACE_EXISTING);
}
}