Skip to content

Instantly share code, notes, and snippets.

@ddikman
Last active December 26, 2023 02:42
Show Gist options
  • Save ddikman/667f309706fdf4f68b9fab2827b1bcca to your computer and use it in GitHub Desktop.
Save ddikman/667f309706fdf4f68b9fab2827b1bcca to your computer and use it in GitHub Desktop.
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