Skip to content

Commit bb1dadf

Browse files
committed
Writethrough when saving files
1 parent f75b537 commit bb1dadf

15 files changed

Lines changed: 55 additions & 20 deletions

File tree

Core/Configuration/JsonConfiguration.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -295,8 +295,8 @@ private void OnPropertyChanged([CallerMemberName] string? name = null)
295295
// </summary>
296296
private void SaveConfig()
297297
{
298-
File.WriteAllText(configFile,
299-
JsonConvert.SerializeObject(config, Formatting.Indented));
298+
JsonConvert.SerializeObject(config, Formatting.Indented)
299+
.WriteThroughTo(configFile);
300300
}
301301

302302
/// <summary>

Core/Configuration/StabilityToleranceConfig.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55

66
using Newtonsoft.Json;
77

8+
using CKAN.Extensions;
9+
810
namespace CKAN.Configuration
911
{
1012
[JsonObject(MemberSerialization.OptIn)]
@@ -27,7 +29,8 @@ public bool Save()
2729
{
2830
try
2931
{
30-
File.WriteAllText(path, JsonConvert.SerializeObject(this, Formatting.Indented));
32+
JsonConvert.SerializeObject(this, Formatting.Indented)
33+
.WriteThroughTo(path);
3134
return true;
3235
}
3336
catch

Core/Extensions/IOExtensions.cs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,25 @@ public static class IOExtensions
1717
public static DriveInfo? GetDrive(this DirectoryInfo dir)
1818
=> Utilities.DefaultIfThrows(() => new DriveInfo(dir.FullName));
1919

20+
/// <summary>
21+
/// File.WriteAllText replacement that doesn't sometimes write all NULs instead on Windows.
22+
/// https://stackoverflow.com/questions/54078564
23+
/// </summary>
24+
/// <param name="contents">The string to write</param>
25+
/// <param name="path">Where to save it</param>
26+
public static void WriteThroughTo(this string contents, string path)
27+
{
28+
using (var stream = File.Create(path, contents.Length + 1,
29+
FileOptions.WriteThrough))
30+
using (var writer = new StreamWriter(stream))
31+
{
32+
writer.Write(contents);
33+
// If we don't Flush, the file can be truncated,
34+
// and if we Close, the 'using' block throws an exception
35+
writer.Flush();
36+
}
37+
}
38+
2039
/// <summary>
2140
/// A version of Stream.CopyTo with progress updates.
2241
/// </summary>

Core/GameInstance.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
using CKAN.Configuration;
1616
using CKAN.Games;
1717
using CKAN.Versioning;
18+
using CKAN.Extensions;
1819

1920
namespace CKAN
2021
{
@@ -138,16 +139,14 @@ public void SetCompatibleVersions(List<GameVersion> compatibleVersions)
138139

139140
private void SaveCompatibleVersions()
140141
{
141-
File.WriteAllText(
142-
CompatibleGameVersionsFile(),
143-
JsonConvert.SerializeObject(new CompatibleGameVersions()
142+
JsonConvert.SerializeObject(new CompatibleGameVersions()
144143
{
145144
GameVersionWhenWritten = Version()?.ToString(),
146145
Versions = _compatibleVersions.Select(v => v.ToString())
147146
.OfType<string>()
148147
.ToList()
149148
})
150-
);
149+
.WriteThroughTo(CompatibleGameVersionsFile());
151150
GameVersionWhenCompatibleVersionsWereStored = Version();
152151
}
153152

@@ -203,7 +202,8 @@ public string[] InstallFilters
203202
#pragma warning disable IDE0027
204203
set
205204
{
206-
File.WriteAllText(InstallFiltersFile, JsonConvert.SerializeObject(value));
205+
JsonConvert.SerializeObject(value)
206+
.WriteThroughTo(InstallFiltersFile);
207207
}
208208
#pragma warning restore IDE0027
209209
}

Core/Games/KerbalSpaceProgram/GameVersionProviders/KspBuildMap.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
using CKAN.IO;
1111
using CKAN.Versioning;
12+
using CKAN.Extensions;
1213

1314
namespace CKAN.Games.KerbalSpaceProgram.GameVersionProviders
1415
{
@@ -144,7 +145,7 @@ private bool TrySetRemoteBuildMap(string? userAgent)
144145
{
145146
// Save to disk if parse succeeds
146147
new FileInfo(cachedBuildMapPath).Directory?.Create();
147-
File.WriteAllText(cachedBuildMapPath, json);
148+
json.WriteThroughTo(cachedBuildMapPath);
148149
return true;
149150
}
150151
}

Core/Games/KerbalSpaceProgram2.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,7 @@ public void RefreshVersions(string? userAgent)
156156

157157
// Save to disk if download and parse succeeds
158158
new FileInfo(cachedBuildMapPath).Directory?.Create();
159-
File.WriteAllText(cachedBuildMapPath, json);
159+
json.WriteThroughTo(cachedBuildMapPath);
160160
}
161161
}
162162
catch (Exception e)

Core/Net/NetFileCache.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -674,7 +674,7 @@ private string GetFileHash(string filePath,
674674
cache.Add(filePath, hash);
675675
if (Path.GetDirectoryName(hashFile) == cachePath.FullName)
676676
{
677-
File.WriteAllText(hashFile, hash);
677+
hash.WriteThroughTo(hashFile);
678678
}
679679
return hash;
680680
}

Core/Registry/Tags/ModuleTagList.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
using Newtonsoft.Json;
44

55
using CKAN.IO;
6+
using CKAN.Extensions;
67

78
namespace CKAN
89
{
@@ -32,7 +33,8 @@ public bool Save(string path)
3233
{
3334
try
3435
{
35-
File.WriteAllText(path, JsonConvert.SerializeObject(this, Formatting.Indented));
36+
JsonConvert.SerializeObject(this, Formatting.Indented)
37+
.WriteThroughTo(path);
3638
return true;
3739
}
3840
catch

Core/SuppressedCompatWarningIdentifiers.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
using log4net;
66

77
using CKAN.Versioning;
8+
using CKAN.Extensions;
89

910
namespace CKAN
1011
{
@@ -36,7 +37,8 @@ public static SuppressedCompatWarningIdentifiers LoadFrom(GameVersion? gameVer,
3637

3738
public void SaveTo(string filename)
3839
{
39-
File.WriteAllText(filename, JsonConvert.SerializeObject(this));
40+
JsonConvert.SerializeObject(this)
41+
.WriteThroughTo(filename);
4042
}
4143

4244
private static readonly ILog log = LogManager.GetLogger(typeof(SuppressedCompatWarningIdentifiers));

Core/Types/CkanModule.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
using CKAN.Versioning;
1616
using CKAN.Games;
17+
using CKAN.Extensions;
1718

1819
namespace CKAN
1920
{
@@ -461,7 +462,7 @@ public static CkanModule FromFile(string filename)
461462

462463
public static void ToFile(CkanModule module, string filename)
463464
{
464-
File.WriteAllText(filename, ToJson(module));
465+
ToJson(module).WriteThroughTo(filename);
465466
}
466467

467468
public static string ToJson(CkanModule module)

0 commit comments

Comments
 (0)