Vereinsmeisterschaften  22aa7800eae54b428d40e835886cefe1fdefdfdf
This is a software that can be used to manage the internal competition of the swimming club Illertissen called "Vereinsmeisterschaften".
Loading...
Searching...
No Matches
FileService.cs
1using System.Reflection;
2using System.Text;
3using Newtonsoft.Json;
5
7
12{
20 public T Read<T>(string folderPath, string fileName)
21 {
22 var path = Path.Combine(folderPath, fileName);
23 if (File.Exists(path))
24 {
25 var json = File.ReadAllText(path);
26 return JsonConvert.DeserializeObject<T>(json);
27 }
28
29 return default;
30 }
31
32 // ----------------------------------------------------------------------------------------------------------------------------------------------
33
41 public void Save<T>(string folderPath, string fileName, T content)
42 {
43 if (!Directory.Exists(folderPath))
44 {
45 Directory.CreateDirectory(folderPath);
46 }
47
48 var fileContent = JsonConvert.SerializeObject(content, Formatting.Indented);
49 File.WriteAllText(Path.Combine(folderPath, fileName), fileContent, Encoding.UTF8);
50 }
51
52 // ----------------------------------------------------------------------------------------------------------------------------------------------
53
59 public void Delete(string folderPath, string fileName)
60 {
61 if (fileName != null && File.Exists(Path.Combine(folderPath, fileName)))
62 {
63 File.Delete(Path.Combine(folderPath, fileName));
64 }
65 }
66
67 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
68
80 public void SaveToCsv<T>(string filePath, List<T> dataList, CancellationToken cancellationToken, ProgressDelegate onProgress = null, FormatDataDelegate formatData = null, FormatDataHeaderDelegate formatDataHeader = null, char delimiter = ';')
81 {
82 // https://stackoverflow.com/questions/25683161/fastest-way-to-convert-a-list-of-objects-to-csv-with-each-object-values-in-a-new
83 onProgress?.Invoke(this, 0);
84 List<string> lines = new List<string>();
85
86 List<PropertyInfo> props = typeof(T).GetProperties().ToList();
87 props = props.Where(p => p.GetCustomAttributes<FileServiceIgnoreAttribute>().Count() == 0).ToList();
88 props = props.OrderBy(p => p.GetCustomAttribute<FileServiceOrderAttribute>()?.Order ?? 0).ToList();
89
90 List<string> originalHeaders = props.Select(p => p.Name).ToList();
91 List<string> formatedHeaders = props.Select(p => formatDataHeader == null ? p.Name : formatDataHeader(p.Name, p.PropertyType)).ToList();
92
93 lines.Add(string.Join(delimiter.ToString(), formatedHeaders));
94
95 int processedElementsCnt = 0;
96 foreach (T data in dataList)
97 {
98 string line = string.Empty;
99 foreach (string header in originalHeaders)
100 {
101 PropertyInfo propInfo = typeof(T).GetProperty(header);
102 object dataObj = propInfo?.GetValue(data, null);
103 if(formatData != null)
104 {
105 line += formatData(dataObj, data, propInfo);
106 }
107 else
108 {
109 line += dataObj;
110 }
111 line += delimiter;
112 }
113 line = line.Trim(delimiter);
114 lines.Add(line);
115 cancellationToken.ThrowIfCancellationRequested();
116
117 // 100 % shouldn't be reported here. Better do this after saving
118 if ((processedElementsCnt + 1) < dataList.Count)
119 {
120 onProgress?.Invoke(this, (processedElementsCnt++ / (float)dataList.Count) * 100);
121 }
122 }
123
124 File.WriteAllLines(filePath, lines.ToArray(), Encoding.UTF8);
125 onProgress?.Invoke(this, 100);
126 }
127
128 // ----------------------------------------------------------------------------------------------------------------------------------------------
129
141 public List<T> LoadFromCsv<T>(string filePath, CancellationToken cancellationToken, SetPropertyFromStringDelegate<T> setPropertyFromStringDelegate, ProgressDelegate onProgress = null, FindPropertyFromHeaderDelegate findPropertyFromHeader = null, char delimiter = ';') where T : new()
142 {
143 List<T> dataList = new List<T>();
144 if (!File.Exists(filePath)) { return dataList; }
145
146 onProgress?.Invoke(this, 0);
147
148 List<string> lines = File.ReadAllLines(filePath, Encoding.UTF8).ToList();
149 if (lines.Count >= 2)
150 {
151 List<string> headers = lines.First().Split(delimiter).ToList();
152 lines.RemoveAt(0);
153
154 int processedElementsCnt = 0;
155 foreach (string line in lines)
156 {
157 List<string> lineParts = line.Split(delimiter).ToList();
158 T data = new T();
159 for (int i = 0; i < Math.Min(headers.Count, lineParts.Count); i++)
160 {
161 string header = findPropertyFromHeader == null ? headers[i] : findPropertyFromHeader(headers[i]);
162 setPropertyFromStringDelegate(data, header, lineParts[i]);
163 cancellationToken.ThrowIfCancellationRequested();
164 }
165 dataList.Add(data);
166
167 onProgress?.Invoke(this, (processedElementsCnt++ / (float)lines.Count) * 100);
168 }
169 }
170 onProgress?.Invoke(this, 100);
171 return dataList;
172 }
173
174}
Use this attribute to decorate elements that should not be saved to a file.
Use this attribute to order some elements to their position in the file.
Service that handles file operations.
void SaveToCsv< T >(string filePath, List< T > dataList, CancellationToken cancellationToken, ProgressDelegate onProgress=null, FormatDataDelegate formatData=null, FormatDataHeaderDelegate formatDataHeader=null, char delimiter=';')
Save the given data list to a .csv file.
void Save< T >(string folderPath, string fileName, T content)
Save the given object to a file.
List< T > LoadFromCsv< T >(string filePath, CancellationToken cancellationToken, SetPropertyFromStringDelegate< T > setPropertyFromStringDelegate, ProgressDelegate onProgress=null, FindPropertyFromHeaderDelegate findPropertyFromHeader=null, char delimiter=';')
Load the .csv file to a list of data.
void Delete(string folderPath, string fileName)
Delete the given file.
T Read< T >(string folderPath, string fileName)
Read the given file and deserialize it to the given type.
Interface for a service that handles file operations.
delegate void SetPropertyFromStringDelegate< T >(T dataObj, string propertyName, string value)
Delegate to change a specific property in the data object.
delegate void ProgressDelegate(object sender, float progress, string currentStep="")
Delegate void for progress changes.
delegate string FormatDataHeaderDelegate(string header, Type type)
Delegate to format data headers.
delegate string FindPropertyFromHeaderDelegate(string header)
Delegate to find propety name by localized header string.
delegate string FormatDataDelegate(object data, object parentObject, PropertyInfo currentProperty)
Delegate to format data.