Merge pull request #395 from NextTurn/move

Implement atomic file movement
pull/385/head
Oleg Nenashev 2020-02-10 05:40:36 -05:00 committed by GitHub
commit ad329b60ca
4 changed files with 50 additions and 19 deletions

View File

@ -106,7 +106,7 @@ namespace winsw
continue;
}
CopyFile(tokens[0], tokens[1]);
MoveFile(tokens[0], tokens[1]);
}
}
finally
@ -118,16 +118,15 @@ namespace winsw
/// <summary>
/// File replacement.
/// </summary>
private void CopyFile(string sourceFileName, string destFileName)
private void MoveFile(string sourceFileName, string destFileName)
{
try
{
File.Delete(destFileName);
File.Move(sourceFileName, destFileName);
FileHelper.MoveOrReplaceFile(sourceFileName, destFileName);
}
catch (IOException e)
{
LogEvent("Failed to copy :" + sourceFileName + " to " + destFileName + " because " + e.Message);
LogEvent("Failed to move :" + sourceFileName + " to " + destFileName + " because " + e.Message);
}
}

View File

@ -181,14 +181,7 @@ namespace winsw
#endif
}
#if NETCOREAPP
File.Move(tmpFilePath, To, true);
#else
if (File.Exists(To))
File.Delete(To);
File.Move(tmpFilePath, To);
#endif
FileHelper.MoveOrReplaceFile(To + ".tmp", To);
}
#if NET20

View File

@ -8,6 +8,7 @@ using System.Threading;
#if !VNEXT
using ICSharpCode.SharpZipLib.Zip;
#endif
using winsw.Util;
namespace winsw
{
@ -52,16 +53,15 @@ namespace winsw
/// <summary>
/// File replacement.
/// </summary>
protected void CopyFile(string sourceFileName, string destFileName)
protected void MoveFile(string sourceFileName, string destFileName)
{
try
{
File.Delete(destFileName);
File.Move(sourceFileName, destFileName);
FileHelper.MoveOrReplaceFile(sourceFileName, destFileName);
}
catch (IOException e)
{
EventLogger.LogEvent("Failed to copy :" + sourceFileName + " to " + destFileName + " because " + e.Message);
EventLogger.LogEvent("Failed to move :" + sourceFileName + " to " + destFileName + " because " + e.Message);
}
}
}
@ -286,10 +286,10 @@ namespace winsw
public override void log(StreamReader outputReader, StreamReader errorReader)
{
if (!OutFileDisabled)
CopyFile(OutputLogFileName, OutputLogFileName + ".old");
MoveFile(OutputLogFileName, OutputLogFileName + ".old");
if (!ErrFileDisabled)
CopyFile(ErrorLogFileName, ErrorLogFileName + ".old");
MoveFile(ErrorLogFileName, ErrorLogFileName + ".old");
base.log(outputReader, errorReader);
}

View File

@ -0,0 +1,39 @@
#if !NETCOREAPP
using System.ComponentModel;
#endif
using System.IO;
#if !NETCOREAPP
using System.Runtime.InteropServices;
#endif
namespace winsw.Util
{
public static class FileHelper
{
public static void MoveOrReplaceFile(string sourceFileName, string destFileName)
{
#if NETCOREAPP
File.Move(sourceFileName, destFileName, true);
#else
string sourceFilePath = Path.GetFullPath(sourceFileName);
string destFilePath = Path.GetFullPath(destFileName);
if (!NativeMethods.MoveFileEx(sourceFilePath, destFilePath, NativeMethods.MOVEFILE_REPLACE_EXISTING | NativeMethods.MOVEFILE_COPY_ALLOWED))
{
throw new Win32Exception();
}
#endif
}
#if !NETCOREAPP
private static class NativeMethods
{
internal const uint MOVEFILE_REPLACE_EXISTING = 0x01;
internal const uint MOVEFILE_COPY_ALLOWED = 0x02;
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode, EntryPoint = "MoveFileExW")]
internal static extern bool MoveFileEx(string lpExistingFileName, string lpNewFileName, uint dwFlags);
}
#endif
}
}