Advertisement
Guest User

Untitled

a guest
Aug 4th, 2015
165
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.33 KB | None | 0 0
  1. using System;
  2. using System.IO;
  3. using System.Runtime.InteropServices;
  4.  
  5. namespace FilesystemUtils
  6. {
  7. public class AtomicFileStream : FileStream
  8. {
  9. private const int DefaultBufferSize = 4096;
  10. private const string DefaultTempFileSuffix = ".tmp";
  11.  
  12. private readonly string path;
  13. private readonly string tempPath;
  14.  
  15. public static AtomicFileStream Open(string path, FileMode mode)
  16. {
  17. return Open(path, TempFilePath(path), mode, (mode == FileMode.Append ? FileAccess.Write : FileAccess.ReadWrite), FileShare.Read, DefaultBufferSize, FileOptions.None);
  18. }
  19.  
  20. public static AtomicFileStream Open(string path, string tempFilePath, FileMode mode)
  21. {
  22. return Open(path, tempFilePath, mode, (mode == FileMode.Append ? FileAccess.Write : FileAccess.ReadWrite), FileShare.Read, DefaultBufferSize, FileOptions.None);
  23. }
  24.  
  25. public static AtomicFileStream Open(string path, FileMode mode, FileAccess access)
  26. {
  27. return Open(path, TempFilePath(path), mode, access, FileShare.Read, DefaultBufferSize, FileOptions.None);
  28. }
  29.  
  30. public static AtomicFileStream Open(string path, string tempFilePath, FileMode mode, FileAccess access)
  31. {
  32. return Open(path, tempFilePath, mode, access, FileShare.Read, DefaultBufferSize, FileOptions.None);
  33. }
  34.  
  35. public static AtomicFileStream Open(string path, FileMode mode, FileAccess access, FileShare share)
  36. {
  37. return Open(path, TempFilePath(path), mode, access, share, DefaultBufferSize, FileOptions.None);
  38. }
  39.  
  40. public static AtomicFileStream Open(string path, string tempFilePath, FileMode mode, FileAccess access, FileShare share)
  41. {
  42. return Open(path, tempFilePath, mode, access, share, DefaultBufferSize, FileOptions.None);
  43. }
  44.  
  45. public static AtomicFileStream Open(string path, FileMode mode, FileAccess access, FileShare share, int bufferSize)
  46. {
  47. return Open(path, TempFilePath(path), mode, access, share, bufferSize, FileOptions.None);
  48. }
  49.  
  50. public static AtomicFileStream Open(string path, FileMode mode, FileAccess access, FileShare share, int bufferSize, bool useAsync)
  51. {
  52. return Open(path, TempFilePath(path), mode, access, share, bufferSize, useAsync ? FileOptions.Asynchronous : FileOptions.None);
  53. }
  54.  
  55. public static AtomicFileStream Open(string path, string tempFilePath, FileMode mode, FileAccess access, FileShare share, int bufferSize, bool useAsync)
  56. {
  57. return Open(path, tempFilePath, mode, access, share, bufferSize, useAsync ? FileOptions.Asynchronous : FileOptions.None);
  58. }
  59.  
  60. public static AtomicFileStream Open(string path, FileMode mode, FileAccess access, FileShare share, int bufferSize, FileOptions options)
  61. {
  62. return Open(path, TempFilePath(path), mode, access, share, bufferSize, options);
  63. }
  64.  
  65. public static AtomicFileStream Open(string path, string tempPath, FileMode mode, FileAccess access, FileShare share, int bufferSize, FileOptions options)
  66. {
  67. if (access == FileAccess.Read)
  68. throw new ArgumentException("If you're just opening the file for reading, AtomicFileStream won't help you at all");
  69.  
  70. if (File.Exists(tempPath))
  71. File.Delete(tempPath);
  72.  
  73. if (File.Exists(path) && (mode == FileMode.Append || mode == FileMode.Open || mode == FileMode.OpenOrCreate))
  74. File.Copy(path, tempPath);
  75.  
  76. return new AtomicFileStream(path, tempPath, mode, access, share, bufferSize, options);
  77. }
  78.  
  79. public static FileStream OpenWrite(string path)
  80. {
  81. return AtomicFileStream.Open(path, FileMode.OpenOrCreate, FileAccess.Write, FileShare.None);
  82. }
  83.  
  84. private AtomicFileStream(string path, string tempPath, FileMode mode, FileAccess access, FileShare share, int bufferSize, FileOptions options)
  85. : base(tempPath, mode, access, share, bufferSize, options)
  86. {
  87. if (path == null)
  88. throw new ArgumentNullException("path");
  89. if (tempPath == null)
  90. throw new ArgumentNullException("tempPath");
  91.  
  92. this.path = path;
  93. this.tempPath = tempPath;
  94. }
  95.  
  96. private static string TempFilePath(string path)
  97. {
  98. return path + DefaultTempFileSuffix;
  99. }
  100.  
  101. public override void Close()
  102. {
  103. base.Close();
  104.  
  105. bool success = NativeMethods.MoveFileEx(this.tempPath, this.path, MoveFileFlags.ReplaceExisting | MoveFileFlags.WriteThrough);
  106. if (!success)
  107. Marshal.ThrowExceptionForHR(Marshal.GetLastWin32Error());
  108. }
  109.  
  110. [Flags]
  111. private enum MoveFileFlags
  112. {
  113. None = 0,
  114. ReplaceExisting = 1,
  115. CopyAllowed = 2,
  116. DelayUntilReboot = 4,
  117. WriteThrough = 8,
  118. CreateHardlink = 16,
  119. FailIfNotTrackable = 32,
  120. }
  121.  
  122. private static class NativeMethods
  123. {
  124. [DllImport("Kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
  125. public static extern bool MoveFileEx(
  126. [In] string lpExistingFileName,
  127. [In] string lpNewFileName,
  128. [In] MoveFileFlags dwFlags);
  129. }
  130. }
  131. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement