Example class for file operation on high contention files
using System; | |
using System.Diagnostics; | |
using System.IO; | |
using System.Text; | |
namespace Stuffsie | |
{ | |
/// <summary>Wraps concurrent file operations, ensuring access is available to a file before reading or writing</summary> | |
public static class ConcurrentFile | |
{ | |
public static byte[] ReadAllBytes(string path, int timeoutMs = 1000) | |
{ | |
using (var stream = GetStream(path, FileMode.Open, FileAccess.Read, timeoutMs)) | |
{ | |
var buffer = new byte[stream.Length]; | |
stream.Read(buffer, 0, buffer.Length); | |
return buffer; | |
} | |
} | |
public static void WriteAllBytes(string path, byte[] contents, int timeoutMs = 1000) | |
{ | |
using (var stream = GetStream(path, FileMode.Create, FileAccess.Write, timeoutMs)) | |
stream.Write(contents, 0, contents.Length); | |
} | |
public static void WriteAllText(string path, string contents, int timeoutMs = 1000) | |
{ | |
WriteAllBytes(path, Encoding.UTF8.GetBytes(contents), timeoutMs); | |
} | |
private static FileStream GetStream(string path, FileMode mode, FileAccess access, int timeoutMs = 1000) | |
{ | |
var time = Stopwatch.StartNew(); | |
while (time.ElapsedMilliseconds < timeoutMs) | |
{ | |
try | |
{ | |
return new FileStream(path, mode, access); | |
} | |
catch (IOException e) | |
{ | |
// access error | |
if (e.HResult != -2147024864) | |
throw; | |
} | |
} | |
throw new TimeoutException($"Failed to get a access to {path} within {timeoutMs}ms."); | |
} | |
/// <summary>Deletes te file if it exists</summary> | |
/// <returns>True if the file was deleted</returns> | |
public static bool Delete(string filename, int timeoutMs = 1000) | |
{ | |
var time = Stopwatch.StartNew(); | |
while (time.ElapsedMilliseconds < timeoutMs) | |
{ | |
try | |
{ | |
if (!File.Exists(filename)) | |
return false; | |
File.Delete(filename); | |
return true; | |
} | |
catch (IOException e) | |
{ | |
// access error | |
if (e.HResult != -2147024864) | |
throw; | |
} | |
} | |
throw new TimeoutException($"Failed to get a access to {filename} within {timeoutMs}ms."); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment