/// <summary> /// Instantiates a new CSV reader for the given stream, which must be formatted according to the given CSV format. /// </summary> /// <param name="stream">The input stream containing a CSV formatted document, will be converted to StreamReader</param> /// <param name="format">Describes the format of the CSV document in the stream</param> public CsvReader(Stream stream, CsvFormat format) : this(new StreamReader(stream), format) { //empty constructor for backwards compatibiltiy, inherits this(TextReader, CsvFormat) }
public int ProcessStream(string documentName, Stream inputStream, Stream?outputMessageStream, CsvFormat format, int processingSetSize, int startAtRecord) { if (inputStream == null) { throw new ArgumentNullException(nameof(inputStream)); } if (format == null) { throw new ArgumentNullException(nameof(format)); } if (processingSetSize > 0 && this.setHandler == null) { throw new InvalidOperationException( "Recordset processing cannot be used on a CSV handler that does not implement ICsvSetHandler"); } if (outputMessageStream != null && !outputMessageStream.CanWrite) { throw new ArgumentException("Stream is not ready for writing", nameof(outputMessageStream)); } var reader = new CsvReader(inputStream, format); var fileStopWatch = new System.Diagnostics.Stopwatch(); var recordStopWatch = new System.Diagnostics.Stopwatch(); //ensure stream is set to position 0 if (inputStream.Position > 0) { inputStream.Position = 0; } //headers are automatically extracted by CsvReader handler.BeginProcessing(documentName, format.Headers); //prepare output stream for writing StreamWriter?outputMessageWriter = outputMessageStream != null ? new StreamWriter(outputMessageStream) : null; fileStopWatch.Start(); //skip to start record while (reader.LinePosition < startAtRecord) { reader.ReadLine(); } //prepare recordset for set processing if (processingSetSize > 0) { this.recordSet = new List <List <string?> >(processingSetSize); } try { while (!reader.EndOfStream) { try { if (processingSetSize < 1) { ProcessRecordwise(reader, outputMessageWriter, recordStopWatch); } else { ProcessSetWise(processingSetSize, reader, outputMessageWriter, recordStopWatch); } } catch (Exception ex) { if (outputMessageWriter != null) { //handled by CsvHandler outputMessageWriter.WriteLine(string.Format("{0}: Error: {1}", reader.LinePosition, this.handler.HandleRecordError(ex))); } else { throw; } } } } catch (Exception ex) { if (outputMessageWriter != null) { //handled by CsvProcessor outputMessageWriter.WriteLine(string.Format("{0}: Error: {1}", reader.LinePosition, ex.Message)); } else { throw; } } fileStopWatch.Stop(); handler.EndProcessing(); outputMessageWriter?.WriteLine(string.Format("Finished processing {0}, did {1} records in {2} seconds.", documentName, reader.LinePosition, fileStopWatch.ElapsedMilliseconds / 1000m)); outputMessageWriter?.Flush(); return(reader.LinePosition); }
/// <summary> /// Writes a field value to the stream /// </summary> /// <param name="field"></param> public void WriteField(string?field) { if (writer == null) { throw new InvalidOperationException($"{nameof(writer)} was null"); } //verify if text qualifiers must be added if (field == null) { this.writer.Write(string.Empty); } else if (this.Format.TextQualifier.HasValue) { //remove text qualifiers from field field = field.Replace(this.Format.TextQualifier.Value, '\0'); //write value //if selected TextQualificationOption applies, wrap in text qualifier if ( this.Format.TextQualification == CsvFormat.TextQualificationOption.ForAllFields || (this.Format.TextQualification == CsvFormat.TextQualificationOption.OnlyWhenNecessary && this.Format.ContainsSeparators(field)) || (this.Format.TextQualification == CsvFormat.TextQualificationOption.ForTextFields && (CsvFormat.ContainsText(field) || this.Format.ContainsSeparators(field)))) { this.writer.Write(this.Format.TextQualifier.Value); this.writer.Write(field); this.writer.Write(this.Format.TextQualifier.Value); } else { this.writer.Write(field); } } else { this.writer.Write(field); } }
/// <summary> /// Processes a CSV formatted <see cref="T:System.IO.Stream"/>. /// </summary> /// <param name="documentName">A descriptive name for the processed document, for logging purposes.</param> /// <param name="inputStream">A CSV formatted stream containing data to be processed.</param> /// <param name="format">A <see cref="T:Simmetric.IO.Csv.CsvFormat"/> object representing the formatting used in the stream.</param> public int ProcessStream(string documentName, Stream inputStream, CsvFormat format) { return(ProcessStream(documentName, inputStream, null, format, 0, 0)); }
/// <summary> /// Processes a CSV formatted <see cref="T:System.IO.Stream"/>. /// </summary> /// <param name="documentName">A descriptive name for the processed document, for logging purposes.</param> /// <param name="inputStream">A CSV formatted stream containing data to be processed.</param> /// <param name="format">A <see cref="T:Simmetric.IO.Csv.CsvFormat"/> object representing the formatting used in the stream.</param> /// <param name="processingSetSize">To process records in sets instead of individually, enter a set size larger than 1. The CsvHandler must implement <see cref="Simmetric.IO.Csv.ICsvSetHandler"/> to support this.</param> public int ProcessStream(string documentName, Stream inputStream, CsvFormat format, int processingSetSize) { return(ProcessStream(documentName, inputStream, null, format, processingSetSize, 0)); }
/// <summary> /// Processes a CSV formatted string. /// </summary> /// <param name="documentName">A descriptive name for the processed document, for logging purposes.</param> /// <param name="csvContent">A CSV formatted string</param> /// <param name="format">A <see cref="T:Simmetric.IO.Csv.CsvFormat"/> object representing the formatting used in the stream.</param> /// <param name="processingSetSize">To pera orocess records in sets instead of individually, enter a set size larger than 1. The CsvHandler must implement <see cref="Simmetric.IO.Csv.ICsvSetHandler"/> to support this.</param> /// <param name="startAtRecord">The parser will skip to the record number indicated.</param> /// <returns>An object containing the number of rows processed and the output messaging.</returns> public CsvProcessorResult <string> ProcessCsv(string documentName, string csvContent, CsvFormat format, int processingSetSize, int startAtRecord) { var outputStream = new MemoryStream(); int rowsProcessed = ProcessStream( documentName, new MemoryStream(System.Text.Encoding.UTF8.GetBytes(csvContent)), outputStream, format, processingSetSize, startAtRecord ); var output = new StreamReader(outputStream).ReadToEnd(); outputStream.Dispose(); return(new CsvProcessorResult <string>(rowsProcessed, output)); }
/// <summary> /// Processes a CSV formatted string. /// </summary> /// <param name="documentName">A descriptive name for the processed document, for logging purposes.</param> /// <param name="csvContent">A CSV formatted string</param> /// <param name="format">A <see cref="T:Simmetric.IO.Csv.CsvFormat"/> object representing the formatting used in the stream.</param> /// <param name="processingSetSize">To pera orocess records in sets instead of individually, enter a set size larger than 1. The CsvHandler must implement <see cref="Simmetric.IO.Csv.ICsvSetHandler"/> to support this.</param> /// <returns>An object containing the number of rows processed and the output messaging.</returns> public CsvProcessorResult <string> ProcessCsv(string documentName, string csvContent, CsvFormat format, int processingSetSize) { return(ProcessCsv(documentName, csvContent, format, processingSetSize, 0)); }
/// <summary> /// Processes a CSV formatted string. /// </summary> /// <param name="documentName">A descriptive name for the processed document, for logging purposes.</param> /// <param name="csvContent">A CSV formatted string</param> /// <param name="format">A <see cref="T:Simmetric.IO.Csv.CsvFormat"/> object representing the formatting used in the stream.</param> /// <returns>An object containing the number of rows processed and the output messaging.</returns> public CsvProcessorResult <string> ProcessCsv(string documentName, string csvContent, CsvFormat format) { return(ProcessCsv(documentName, csvContent, format, 0, 0)); }
/// <summary> /// Processes a CSV formatted file and logs output messages to a file in the same location with suffix '-output.txt' /// </summary> /// <param name="fileName">Full path to the file.</param> /// <param name="format">A <see cref="T:Simmetric.IO.Csv.CsvFormat"/> object representing the formatting used in the stream.</param> /// <param name="processingSetSize">To process records in sets instead of individually, enter a set size larger than 1. The CsvHandler must implement <see cref="Simmetric.IO.Csv.ICsvSetHandler"/> to support this.</param> /// <returns>The number of rows processed</returns> public int ProcessFile(string fileName, CsvFormat format, int processingSetSize) { return(ProcessFile(fileName, format, processingSetSize, 0)); }
/// <summary> /// Processes a CSV formatted file and logs output messages to a file in the same location with suffix '-output.txt' /// </summary> /// <param name="fileName">Full path to the file.</param> /// <param name="format">A <see cref="T:Simmetric.IO.Csv.CsvFormat"/> object representing the formatting used in the stream.</param> /// <returns>The number of rows processed</returns> public int ProcessFile(string fileName, CsvFormat format) { return(ProcessFile(fileName, format, 0, 0)); }