Last active
December 26, 2023 02:42
-
-
Save ddikman/667f309706fdf4f68b9fab2827b1bcca to your computer and use it in GitHub Desktop.
Example class for file operation on high contention files
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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