mirror of
https://github.com/Flow-Launcher/Flow.Launcher.git
synced 2026-03-11 08:54:32 +00:00
Merge pull request #1763 from Flow-Launcher/atomic_setting_save
Atomic Save for Setting
This commit is contained in:
commit
3a3da51d92
4 changed files with 59 additions and 42 deletions
4
.github/actions/spelling/expect.txt
vendored
4
.github/actions/spelling/expect.txt
vendored
|
|
@ -62,6 +62,8 @@ TobiasSekan
|
||||||
Img
|
Img
|
||||||
img
|
img
|
||||||
resx
|
resx
|
||||||
|
bak
|
||||||
|
tmp
|
||||||
directx
|
directx
|
||||||
mvvm
|
mvvm
|
||||||
dlg
|
dlg
|
||||||
|
|
@ -85,4 +87,4 @@ searchplugin
|
||||||
Noresult
|
Noresult
|
||||||
wpftk
|
wpftk
|
||||||
mkv
|
mkv
|
||||||
flac
|
flac
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,6 @@
|
||||||
using System;
|
#nullable enable
|
||||||
|
|
||||||
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
|
|
@ -16,7 +18,7 @@ namespace Flow.Launcher.Infrastructure
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// http://www.yinwang.org/blog-cn/2015/11/21/programming-philosophy
|
/// http://www.yinwang.org/blog-cn/2015/11/21/programming-philosophy
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static T NonNull<T>(this T obj)
|
public static T NonNull<T>(this T? obj)
|
||||||
{
|
{
|
||||||
if (obj == null)
|
if (obj == null)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
using System;
|
#nullable enable
|
||||||
|
using System;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
|
|
@ -11,62 +12,73 @@ namespace Flow.Launcher.Infrastructure.Storage
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class JsonStorage<T> where T : new()
|
public class JsonStorage<T> where T : new()
|
||||||
{
|
{
|
||||||
protected T _data;
|
protected T? Data;
|
||||||
// need a new directory name
|
// need a new directory name
|
||||||
public const string DirectoryName = "Settings";
|
public const string DirectoryName = "Settings";
|
||||||
public const string FileSuffix = ".json";
|
public const string FileSuffix = ".json";
|
||||||
public string FilePath { get; set; }
|
protected string FilePath { get; init; } = null!;
|
||||||
public string DirectoryPath { get; set; }
|
private string TempFilePath => $"{FilePath}.tmp";
|
||||||
|
private string BackupFilePath => $"{FilePath}.bak";
|
||||||
|
protected string DirectoryPath { get; init; } = null!;
|
||||||
|
|
||||||
|
|
||||||
public T Load()
|
public T Load()
|
||||||
{
|
{
|
||||||
|
string? serialized = null;
|
||||||
|
|
||||||
if (File.Exists(FilePath))
|
if (File.Exists(FilePath))
|
||||||
{
|
{
|
||||||
var serialized = File.ReadAllText(FilePath);
|
serialized = File.ReadAllText(FilePath);
|
||||||
if (!string.IsNullOrWhiteSpace(serialized))
|
}
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(serialized))
|
||||||
|
{
|
||||||
|
try
|
||||||
{
|
{
|
||||||
Deserialize(serialized);
|
Data = JsonSerializer.Deserialize<T>(serialized)?? TryLoadBackup() ?? LoadDefault();
|
||||||
}
|
}
|
||||||
else
|
catch (JsonException)
|
||||||
{
|
{
|
||||||
LoadDefault();
|
Data = TryLoadBackup() ?? LoadDefault();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
LoadDefault();
|
Data = TryLoadBackup() ?? LoadDefault();
|
||||||
}
|
}
|
||||||
return _data.NonNull();
|
return Data.NonNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Deserialize(string serialized)
|
private T LoadDefault()
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
_data = JsonSerializer.Deserialize<T>(serialized);
|
|
||||||
}
|
|
||||||
catch (JsonException e)
|
|
||||||
{
|
|
||||||
LoadDefault();
|
|
||||||
Log.Exception($"|JsonStorage.Deserialize|Deserialize error for json <{FilePath}>", e);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_data == null)
|
|
||||||
{
|
|
||||||
LoadDefault();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void LoadDefault()
|
|
||||||
{
|
{
|
||||||
if (File.Exists(FilePath))
|
if (File.Exists(FilePath))
|
||||||
{
|
{
|
||||||
BackupOriginFile();
|
BackupOriginFile();
|
||||||
}
|
}
|
||||||
|
|
||||||
_data = new T();
|
return new T();
|
||||||
Save();
|
}
|
||||||
|
|
||||||
|
private T? TryLoadBackup()
|
||||||
|
{
|
||||||
|
if (!File.Exists(BackupFilePath))
|
||||||
|
return default;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var data = JsonSerializer.Deserialize<T>(File.ReadAllText(BackupFilePath));
|
||||||
|
if (data != null)
|
||||||
|
{
|
||||||
|
Log.Info($"|JsonStorage.Load|Failed to load settings.json, {BackupFilePath} restored successfully");
|
||||||
|
File.Replace(BackupFilePath, FilePath, null);
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
return default;
|
||||||
|
}
|
||||||
|
catch (JsonException)
|
||||||
|
{
|
||||||
|
return default;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void BackupOriginFile()
|
private void BackupOriginFile()
|
||||||
|
|
@ -82,13 +94,14 @@ namespace Flow.Launcher.Infrastructure.Storage
|
||||||
|
|
||||||
public void Save()
|
public void Save()
|
||||||
{
|
{
|
||||||
string serialized = JsonSerializer.Serialize(_data, new JsonSerializerOptions() { WriteIndented = true });
|
string serialized = JsonSerializer.Serialize(Data, new JsonSerializerOptions
|
||||||
|
{
|
||||||
|
WriteIndented = true
|
||||||
|
});
|
||||||
|
|
||||||
File.WriteAllText(FilePath, serialized);
|
File.WriteAllText(TempFilePath, serialized);
|
||||||
|
File.Replace(TempFilePath, FilePath, BackupFilePath);
|
||||||
|
File.Delete(TempFilePath);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[Obsolete("Deprecated as of Flow Launcher v1.8.0, on 2021.06.21. " +
|
|
||||||
"This is used only for Everything plugin v1.4.9 or below backwards compatibility")]
|
|
||||||
public class JsonStrorage<T> : JsonStorage<T> where T : new() { }
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ namespace Flow.Launcher.Infrastructure.Storage
|
||||||
|
|
||||||
public PluginJsonStorage(T data) : this()
|
public PluginJsonStorage(T data) : this()
|
||||||
{
|
{
|
||||||
_data = data;
|
Data = data;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue