|
| 1 | +# Developer Guide |
| 2 | +## i. Installation: Nuget |
| 3 | +Install the latest version of nuget package using the command below. |
| 4 | +``` |
| 5 | +NuGet\Install-Package FixedWidth.FileParser |
| 6 | +``` |
| 7 | + |
| 8 | +## ii. Implementation: Using FileUtil |
| 9 | +**Case 1:** Let us see how we can parse a delimiter separted file with no header and footer rows. |
| 10 | +------------------------------------------------------------------------ |
| 11 | + |
| 12 | + |
| 13 | +**Note:** This file will have rows with no line head as all lines are of same type |
| 14 | +*ie. default is type of data.* |
| 15 | + |
| 16 | +> For the example rows below, we can parse the file with just few lines of code and minimal configuration. |
| 17 | +> |
| 18 | + |Mr|Jack Marias|Male|London| |
| 19 | + |Dr|Bony Stringer|Male|New Jersey| |
| 20 | + |Mrs|Mary Ward|Female|| |
| 21 | + |Mr|Robert Webb||| |
| 22 | +> |
| 23 | +
|
| 24 | +**Configuration** |
| 25 | +------------- |
| 26 | + |
| 27 | +We can configure the parser and provider setting for FileUtil to override the defaults. |
| 28 | + |
| 29 | +The below configuration shows the complete set of attributes required to parse a delimiter separated file with no header or footer rows. |
| 30 | + |
| 31 | +At a minimal you can specify the folder location `{"providerSettings":{ "folderPath":"C:work"}` where the source file will reside. You can override defaults as required. |
| 32 | + |
| 33 | +By default, the file is read using the default file system provider. You can pass in your own implementation of the provider > to custom read file from desired location. We will later show how you can acheive this. |
| 34 | + |
| 35 | + |
| 36 | + { |
| 37 | + "configSettings":{ |
| 38 | + "parserSettings": { "delimiter":{ "value":"|"} }, |
| 39 | + "providerSettings": { |
| 40 | + "folderPath":"C:work", |
| 41 | + "fileNameFormat":"File*.txt", |
| 42 | + "archiveUponRead":"true", |
| 43 | + "archiveFolder":"Archived" |
| 44 | + } |
| 45 | + } |
| 46 | +} |
| 47 | + |
| 48 | + |
| 49 | + The `"fileNameFormat":"File*.txt"` attribute (by default is empty) can |
| 50 | + be used to search the folder location for files with a specific name pattern. |
| 51 | + if not specified then all available files in the folder location will be searched. |
| 52 | + |
| 53 | + |
| 54 | + |
| 55 | +**Code** |
| 56 | +------------- |
| 57 | +To parse a row into a C# class, you need to implement **FileLine** abstract class. |
| 58 | +By doing this you create a strongly typed line representation for each row in the file. |
| 59 | + |
| 60 | +Consider the file below - |
| 61 | +> |
| 62 | + |Mr|Jack Marias|Male|London| |
| 63 | + |Dr|Bony Stringer|Male|New Jersey| |
| 64 | + |Mrs|Mary Ward|Female|| |
| 65 | + |Mr|Robert Webb||| |
| 66 | +> |
| 67 | +
|
| 68 | +Let us create an employee class which will hold data for each row shown in the file above. The properties in the line class should match to the column index and data type of the fields of the row. |
| 69 | + |
| 70 | +We use the column attribute to specify the column index and can optionally specify a default value for the associated column should it be be empty. As a rule of thumb, the number of properties with column attributes should match the number of columns in the row else the engine will throw an exception. |
| 71 | + |
| 72 | +FileLine base class has an index property that holds the index of the parsed line relative to the whole file, an array of errors (should there be any column parsing failures) and type property to denote if the file is of type header, data or footer (default is data) |
| 73 | + |
| 74 | + |
| 75 | + public class Employee : FileLine |
| 76 | + { |
| 77 | + [Column(0)] |
| 78 | + public string Title { get; set; } |
| 79 | + [Column(1)] |
| 80 | + public string Name { get; set; } |
| 81 | + [Column(2)] |
| 82 | + public string Sex { get; set; } |
| 83 | + [Column(3, "London")] |
| 84 | + public string Location { get; set; } |
| 85 | + } |
| 86 | + |
| 87 | +Once you have created the line class it is as simple as calling the Engine.GetFile() method as follows |
| 88 | + |
| 89 | +> |
| 90 | + `var files = new Engine(configSettings).GetFiles<Employee>();` |
| 91 | +
|
| 92 | +The engine will parse the files found at the specified folder location and return a collection of |
| 93 | + `File<Employee>` objects ie. one for each file parsed with an array of strongly typed lines (in this case Employee[]). |
| 94 | + |
| 95 | +``` |
| 96 | +public class File<T> where T: FileLine |
| 97 | + { |
| 98 | + /// <summary> |
| 99 | + /// File meta data. |
| 100 | + /// </summary> |
| 101 | + public FileMeta FileMeta { get; set; } |
| 102 | + /// <summary> |
| 103 | + /// Strongly typed parsed lines. |
| 104 | + /// </summary> |
| 105 | + public T[] Data { get; set; } |
| 106 | + |
| 107 | + } |
| 108 | +``` |
| 109 | + |
| 110 | +------------- |
| 111 | + |
| 112 | + |
| 113 | +**Case 2:** Let us see how we can parse a delimiter separted file with header and footer rows. |
| 114 | +------------------------------------------------------------------------ |
| 115 | + |
| 116 | +**Note:** This file will have rows with line head to determine each row type. By default, the line heads are 'H' for header, 'D' for data and 'F' for footer respectively. all these line heads are configurable via the config. |
| 117 | +> |
| 118 | + |H|Department|Jun 23 2016 7:01PM| |
| 119 | + |D|Mr|Jack Marias|Male|London| |
| 120 | + |D|Dr|Bony Stringer|Male|New Jersey| |
| 121 | + |D|Mrs|Mary Ward|Female|| |
| 122 | + |D|Mr|Robert Webb||| |
| 123 | + |F|4 Records| |
| 124 | +> |
| 125 | +
|
| 126 | +**Configuration** |
| 127 | +------------- |
| 128 | + |
| 129 | +The configuration is the same as before. We can override the default line heads by specifying the required line head attribute in the parser settings. |
| 130 | + |
| 131 | +``` |
| 132 | +{ |
| 133 | + "configSettings":{ |
| 134 | + "parserSettings":{ "delimiter": { "value":"|"} , |
| 135 | + "lineHeaders": { |
| 136 | + "header":"H", |
| 137 | + "footer":"F", |
| 138 | + "data":"D" |
| 139 | + } |
| 140 | + }, |
| 141 | + "providerSettings":{ |
| 142 | + "folderPath":"C:work", |
| 143 | + "fileNameFormat":"File*.txt", |
| 144 | + "archiveUponRead":"true", |
| 145 | + "archiveFolder":"Archived" |
| 146 | + } |
| 147 | + } |
| 148 | +} |
| 149 | +``` |
| 150 | + |
| 151 | +**Code** |
| 152 | +------------- |
| 153 | + |
| 154 | +Like before we need a line class to map to each type of the row in the file |
| 155 | +ie one for the header, footer and data line respectively. |
| 156 | + |
| 157 | +We continue by creating two extra classes HeaderLine and FooterLine as follows. |
| 158 | + |
| 159 | + public class Header : FileLine |
| 160 | + { |
| 161 | + [Column(0)] |
| 162 | + public string Name { get; set; } |
| 163 | + [Column(1)] |
| 164 | + public DateTime Date { get; set; } |
| 165 | + } |
| 166 | + |
| 167 | + public class Footer : FileLine |
| 168 | + { |
| 169 | + [Column(0)] |
| 170 | + public string FileRemarks { get; set; } |
| 171 | + } |
| 172 | + |
| 173 | + |
| 174 | +To parse the file you call the GetFiles() Method as follows - |
| 175 | +> |
| 176 | +`var files = new Engine(configSettings).GetFiles<Header, Employee, Footer>();` |
| 177 | +
|
| 178 | +The engine will parse the files and return a collection of `File<Header, Employee, Footer>` objects |
| 179 | +ie. one for each file parsed with strongly typed header, footer and data line arrays. |
| 180 | + |
| 181 | + |
| 182 | +------------- |
| 183 | + |
| 184 | + |
| 185 | +**Custom File Provider:** Let us see how we can implement custom file provider for bespoke requirements. |
| 186 | +------------------------------------------------------------------------ |
| 187 | + |
| 188 | +You can implement your own custom provider and pass it to the engine to provide delimiter separated file lines by implementing your own bespoke logic. This could be reading the contents from the datadase or over http, etc. |
| 189 | + |
| 190 | +To implement a custom provider you need to implement **IFileProvide** interface |
| 191 | + |
| 192 | +An example dummy implementation is as follows |
| 193 | + |
| 194 | + public class CustomProvider : IFileProvider |
| 195 | + { |
| 196 | + public FileMeta[] GetFiles() |
| 197 | + { |
| 198 | + // custom implementation to return file lines |
| 199 | + return new[] |
| 200 | + { |
| 201 | + new FileMeta |
| 202 | + { |
| 203 | + FileName = "Name", |
| 204 | + FileSize = 100, |
| 205 | + FilePath = "File Path", |
| 206 | + Lines = new[] {"H|22-10-2016|Employee Status", "D|John Walsh|456RT4|True", "F|1"} |
| 207 | + } |
| 208 | + }; |
| 209 | + } |
| 210 | + } |
| 211 | + |
| 212 | +You can pass the custom provider to the engine as follows - |
| 213 | + |
| 214 | + `var files = new Engine(configSettings, new CustomProvider()).GetFiles<Employee>();` |
| 215 | + |
| 216 | + `var files = new Engine(configSettings, new CustomProvider()).GetFiles<Header, Employee, Footer>();` |
| 217 | + |
| 218 | +Returns |
| 219 | +``` |
| 220 | +public class File<TH, TD, TF> |
| 221 | + { |
| 222 | + /// <summary> |
| 223 | + /// File meta data. |
| 224 | + /// </summary> |
| 225 | + public FileMeta FileMeta { get; set; } |
| 226 | + /// <summary> |
| 227 | + /// Parsed header lines. |
| 228 | + /// </summary> |
| 229 | + public TH Header { get; set; } |
| 230 | + /// <summary> |
| 231 | + /// Parsed data lines. |
| 232 | + /// </summary> |
| 233 | + public TD[] Data { get; set; } |
| 234 | + /// <summary> |
| 235 | + /// Parsed footer line. |
| 236 | + /// </summary> |
| 237 | + public TF Footer { get; set; } |
| 238 | + } |
| 239 | +``` |
| 240 | + |
| 241 | +------------- |
0 commit comments