Files
HawkeyeVision/framework/Inspectron.Statistics/LockedCsvStatistics.cs
2025-07-14 12:03:59 +02:00

93 lines
2.3 KiB
C#

using System.Globalization;
using CsvHelper;
namespace Inspectron.Statistics;
public class LockedCsvStatistics : IStatistics
{
private readonly string _filePath;
private readonly string _lockFilePath;
private readonly string[] _headers;
public LockedCsvStatistics(string filePath, string[] headers)
{
_filePath = filePath;
_lockFilePath = filePath + ".lock";
_headers = headers;
var directoryPath = Path.GetDirectoryName(filePath);
if (directoryPath != null && !Directory.Exists(directoryPath))
{
Directory.CreateDirectory(directoryPath);
}
}
public void WriteLine(StatisticsRecord record)
{
AcquireLock();
try
{
bool writeHeaders = !File.Exists(_filePath) || new FileInfo(_filePath).Length == 0;
using var fileStream = new FileStream(_filePath, FileMode.Append, FileAccess.Write, FileShare.None);
using var streamWriter = new StreamWriter(fileStream);
using var csvWriter = new CsvWriter(streamWriter, CultureInfo.InvariantCulture);
if (writeHeaders)
{
foreach (var header in _headers)
{
csvWriter.WriteField(header);
}
csvWriter.NextRecord();
csvWriter.Flush();
}
foreach (var value in record.Values)
{
csvWriter.WriteField(value);
}
csvWriter.NextRecord();
csvWriter.Flush();
}
finally
{
ReleaseLock();
}
}
public void Dispose()
{
// No resources to dispose
}
private void AcquireLock()
{
while (true)
{
try
{
using (File.Open(_lockFilePath, FileMode.CreateNew, FileAccess.ReadWrite, FileShare.None))
{
// Lock acquired
break;
}
}
catch (IOException)
{
// Lock file already exists, wait and retry
Thread.Sleep(10);
}
}
}
private void ReleaseLock()
{
if (File.Exists(_lockFilePath))
{
File.Delete(_lockFilePath);
}
}
}