CsvConverterOpenReadAnalyzedTResult(String, CsvMapping, FuncObject, TResult, Encoding, Header, Int32) Method

Opens a CSV file for parsing its data after it had been analyzed.

Definition

Namespace: FolkerKinzel.CsvTools.Mappings
Assembly: FolkerKinzel.CsvTools.Mappings (in FolkerKinzel.CsvTools.Mappings.dll) Version: 1.1.0+1263e8243dc2cd78095f678f813d7d9c52ea4315
C#
public static CsvReader<TResult> OpenReadAnalyzed<TResult>(
	string filePath,
	CsvMapping mapping,
	Func<Object, TResult> conversion,
	Encoding? defaultEncoding = null,
	Header header = Header.ProbablyPresent,
	int analyzedLines = 5
)

Parameters

filePath  String
File path of the CSV file to read.
mapping  CsvMapping
The CsvMapping used to convert the CSV data.
conversion  FuncObject, TResult

A function that converts the content of mapping to an instance of TResult.

The function is called for each row in the CSV file and gets the CsvMapping as argument, filled with the current CsvRecord instance. The CsvMapping is passed to the function as dynamic argument: Inside the function the registered DynamicProperty instances can be used like regular .NET properties, but without IntelliSense ("late binding").

defaultEncoding  Encoding  (Optional)
The text Encoding to be used if the CSV file has no byte order mark (BOM), or null to use UTF8 in this case. Use GetExcelArguments to get the appropriate argument for this parameter when importing CSV data from Excel.
header  Header  (Optional)
A supposition that is made about the presence of a header row.
analyzedLines  Int32  (Optional)
Maximum number of lines to analyze in the CSV file. The minimum value is AnalyzedLinesMinCount. If the file has fewer lines than analyzedLines, it will be analyzed completely. (You can specify Int32.MaxValue to analyze the entire file in any case.)

Type Parameters

TResult
Generic type parameter that specifies the Type of the items that the CsvReaderTResult returns.

Return Value

CsvReaderTResult
A CsvReaderTResult that allows you to iterate through the data parsed from the CSV file.

Remarks

The method performs a statistical analysis on the CSV file. The result of the analysis is therefore always only an estimate, the accuracy of which increases with the number of lines analyzed.

The field delimiters COMMA (',', %x2C), SEMICOLON (';', %x3B), HASH ('#', %x23), TAB ('\t', %x09), and SPACE (' ', %x20) are recognized automatically.

This method also tries to determine the Encoding of the CSV file from the byte order mark (BOM). If no byte order mark can be found, defaultEncoding is used.

Example

  Note

In the following code examples - for easier readability - exception handling has been omitted.

CSV data exchange with Excel:

C#
using FolkerKinzel.CsvTools;
using FolkerKinzel.CsvTools.Mappings;
using System.Globalization;
using System.Text;
// A namespace alias helps to avoid name conflicts
// with the converters from System.ComponentModel
using Conv = FolkerKinzel.CsvTools.Mappings.TypeConverters;

namespace Examples;

internal sealed record Customer(string Name, decimal Sales, DateOnly RecentPurchase);

internal static class ExcelExample
{
    internal static void CsvDataExchangeWithExcel(string filePath)
    {
        // Which field separators and formatting Excel accepts and exports depends on the
        // "Regional Settings" in Excel. The default setting corresponds to the settings
        // of the user's computer (and thus of CultureInfo.CurrentCulture).

        // Using CultureInfo.CurrentCulture, the corresponding parameters can be determined
        // automatically.

        // The application is free to override the value of CurrentCulture for the current
        // Thread if users do not use the default setting in Excel.

        // This example shows the procedure for exporting CSV data to Excel. The procedure
        // for importing is equivalent.(The console output is from a computer with the locale
        // "de-DE".)

        Console.WriteLine("Current culture: {0}", CultureInfo.CurrentCulture);

        Customer[] customers = [ new("Susi", 4_711m, new DateOnly(2004, 3, 14)),
                                 new("Tom", 38_527.28m, new DateOnly(2006, 12, 24)),
                                 new("Sören", 25.8m, new DateOnly(2011, 8, 27)) ];

        // Get the Excel arguments for CultureInfo.CurrentCulture:
        (char delimiter,
         IFormatProvider formatProvider,
         Encoding ansi) = Csv.GetExcelArguments();

        // Pass the formatProvider from the Excel arguments to all localizable converters.
        // (The same CsvMapping can be used for writing and parsing.)
        CsvMapping mapping = CsvMappingBuilder
            .Create()
            .AddProperty("Name", Conv::StringConverter.CreateNonNullable())
            .AddProperty("Sales", new Conv::DecimalConverter(formatProvider))
            .AddProperty("RecentPurchase", new Conv::DateOnlyConverter(formatProvider))
            .Build();

        static void FillMapping(Customer customer, dynamic mapping)
        {
            mapping.Name = customer.Name;
            mapping.Sales = customer.Sales;
            mapping.RecentPurchase = customer.RecentPurchase;
        }

        // Don't forget to pass the delimiter from the Excel arguments!
        // (The textEncoding can be omitted when writing, but not when reading.)
        customers.SaveCsv(filePath, mapping, FillMapping, delimiter, textEncoding: ansi);

        Console.WriteLine();
        Console.WriteLine(File.ReadAllText(filePath, ansi));

        // =================================================

        // Parsing CSV that comes from Excel:

        static Customer InitializeCustomer(dynamic mapping) => new(mapping.Name,
                                                                   mapping.Sales,
                                                                   mapping.RecentPurchase);

        // Using this method allows to switch automatically to Unicode if the file
        // has a byte order mark, and to detect a different delimiter character if 
        // the user had changed the default settings in Excel.
        using CsvReader<Customer> reader = CsvConverter.OpenReadAnalyzed(filePath,
                                                                         mapping,
                                                                         InitializeCustomer,
                                                                         defaultEncoding: ansi);

        Console.WriteLine();
        Console.WriteLine("The customer with the lowest sales is {0}.",
                          reader.MinBy(x => x.Sales)?.Name);
    }
}

/*
 Console output:

Current culture: de-DE

Name;Sales;RecentPurchase
Susi;4711;14.03.2004
Tom;38527,28;24.12.2006
Sören;25,8;27.08.2011

The customer with the lowest sales is Sören.
*/

Exceptions

ArgumentNullExceptionfilePath, or mapping, or conversion is null.
ArgumentOutOfRangeException

header is not a defined value of the Header enum.

- or -

header is a combination of Header values.

CsvFormatExceptionInvalid CSV file. Try to increase the value of analyzedLines to get a better analyzer result!

See Also