93 lines
2.3 KiB
C#
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);
|
|
}
|
|
}
|
|
}
|