/// <summary> /// Saves changed data to .csv file on disk. /// </summary> public void SaveData(string?fileName) { if (_csvDbDirectoryInfo is null) { return; } if (string.IsNullOrWhiteSpace(fileName)) { return; } string fileNameUpper = fileName !.ToUpperInvariant(); if (!_csvFilesCollection.TryGetValue(fileNameUpper, out CsvFile? csvFile)) { return; } if (csvFile.DataIsChangedByProgram) { _fileSystemWatcher.EnableRaisingEvents = false; try { var isNewCsvFile = csvFile.LastWriteTimeUtc == DateTime.MinValue; // If the file to be deleted does not exist, no exception is thrown. File.Delete(csvFile.FileFullName); // For 'a' to 'A' changes in files names to work. using (var writer = new StreamWriter(csvFile.FileFullName, false, new UTF8Encoding(true))) { foreach (var fileLine in csvFile.Data !.OrderBy(kvp => kvp.Key)) { writer.WriteLine(CsvHelper.FormatForCsv(",", fileLine.Value.ToArray())); } } csvFile.LastWriteTimeUtc = File.GetLastWriteTimeUtc(csvFile.FileFullName); if (isNewCsvFile) { CsvFileChanged?.Invoke(CsvFileChangeAction.Added, fileNameUpper); } else { CsvFileChanged?.Invoke(CsvFileChangeAction.Updated, fileNameUpper); } } catch (Exception ex) { _logger?.LogError(ex, Properties.Resources.CsvDb_CsvFileWritingError + " " + csvFile.FileFullName); } csvFile.DataIsChangedByProgram = false; var t = FileSystemWatcherEnableRaisingEventsAsync(); } }
/// <summary> /// Loads data from .csv files on disk. /// Data is loaded in constructor. /// Data is loaded when directory content changes, if dispatcher in consructor is not null. /// </summary> public void LoadData() { if (_csvDbDirectoryInfo is null) { return; } var newCsvFilesCollection = new Dictionary <string, CsvFile>(); foreach (FileInfo fileInfo in _csvDbDirectoryInfo.GetFiles(@"*.csv", SearchOption.TopDirectoryOnly)) { string fileNameUpper = fileInfo.Name.ToUpperInvariant(); _csvFilesCollection.TryGetValue(fileNameUpper, out CsvFile? csvFile); if (csvFile is null) { csvFile = new CsvFile { FileFullName = fileInfo.FullName, LastWriteTimeUtc = fileInfo.LastWriteTimeUtc, DataIsChangedOnDisk = true }; foreach (CsvFile oldCsvFile in _csvFilesCollection.Values) { if (oldCsvFile.IncludeFileNamesCollection.Contains(fileNameUpper)) { oldCsvFile.DataIsChangedOnDisk = true; } } } else if (Path.GetFileNameWithoutExtension(csvFile.FileFullName) != Path.GetFileNameWithoutExtension(fileInfo.FullName) || // Strict compare for 'a' to 'A' changes in files names to work. !FileSystemHelper.FileSystemTimeIsEquals(csvFile.LastWriteTimeUtc, fileInfo.LastWriteTimeUtc)) { csvFile.FileFullName = fileInfo.FullName; csvFile.LastWriteTimeUtc = fileInfo.LastWriteTimeUtc; csvFile.DataIsChangedOnDisk = true; foreach (CsvFile oldCsvFile in _csvFilesCollection.Values) { if (oldCsvFile.IncludeFileNamesCollection.Contains(fileNameUpper)) { oldCsvFile.DataIsChangedOnDisk = true; } } csvFile.MovedToNewCollection = true; } newCsvFilesCollection.Add(fileNameUpper, csvFile); } foreach (var kvp in _csvFilesCollection) { if (!kvp.Value.MovedToNewCollection) { if (kvp.Value.DataIsChangedByProgram) { newCsvFilesCollection.Add(kvp.Key, kvp.Value); } else { // Notify about deleted files CsvFileChanged?.Invoke(CsvFileChangeAction.Removed, kvp.Key); } } } foreach (var kvp in newCsvFilesCollection) { CsvFile csvFile = kvp.Value; if (csvFile.DataIsChangedOnDisk) { csvFile.IncludeFileNamesCollection.Clear(); csvFile.Data = null; csvFile.DataIsChangedOnDisk = false; csvFile.DataIsChangedByProgram = false; // Notify about changed files if (csvFile.MovedToNewCollection) { CsvFileChanged?.Invoke(CsvFileChangeAction.Updated, kvp.Key); } else { CsvFileChanged?.Invoke(CsvFileChangeAction.Added, kvp.Key); } } csvFile.MovedToNewCollection = false; } _csvFilesCollection = newCsvFilesCollection; }