HiveBrain v1.2.0
Get Started
← Back to all entries
patterncsharpMinor

CSV writer implementation

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
writerimplementationcsv

Problem

I've recently been assigned to write up a CSV writer with "as much flexibility" as possible concerning pretty much all (output stream, string fields with potential new line characters, separator collisions, etc. you name it...)

No specification, no design guidelines, no nothing and I'm not expecting any any time soon (let's not dwell on the situation I'm currently in...). So, I've quickly built a test implementation which is as follows:

```
public sealed class CsvWriter : MarshalByRefObject, IDisposable
{
private const int MIN_BUFFER = 8;
private const char ESCAPE_CHAR = '\\';
private const char ESCAPED_SEPARATOR_CHAR = 's';
private Stream output;
private readonly StringBuilder buffer;
private bool isDisposed;
private readonly IEnumerable> projections;
private readonly List ignoredCharacters;
private readonly char listSeparator;
private readonly bool escapeListSeparator;
private readonly Encoding encoding;
private readonly bool escapeNewLineCharacters;
private readonly int bufferLength = 512;

public CsvWriter(Stream output, IEnumerable> projections, Encoding encoding = null, int bufferLength = 512, bool escapeListSeparatorInsideFields = true,
bool escapeNewLineCharacters = true, IEnumerable ignoredCharacters = null)
: this(output, projections, CultureInfo.CurrentCulture.TextInfo.ListSeparator[0], encoding, bufferLength, escapeListSeparatorInsideFields, escapeNewLineCharacters, ignoredCharacters)
{
}

public CsvWriter(Stream output, IEnumerable> projections, char listSeparator, Encoding encoding = null, int bufferLength = 512, bool escapeListSeparatorInsideFields = true,
bool escapeNewLineCharacters = true, IEnumerable ignoredCharacters = null)
{
ArgumentValidator.ArgumentNotNull(output, "output");
ArgumentValidator.ArgumentNotNull(projections, "projections");
ArgumentValidator.ArgumentNotValid(output, b => output.CanWrite, "output", "Can not wri

Solution


  • You should use auto-properties instead of



public IEnumerable IgnoredCharacters
    {
        get
        {
            return this.ignoredCharacters;
        }
    }


It will improve the readability of your code.

-
The recommended naming convention for constants in .Net is Pascal case. So it should be MinBuffer, for example. Same goes for methods (CheckBuffer()).

-
Instead of manually moving your iterator, you should use a foreach loop.

-
Your WriteLine method is too complex. You should probably break it down to smaller parts, so it's easier to understand. I would also encapsulate parsing logic into different class.

-
Your constructor is too complex as well, you should encapsulate those parameters into some class (CswWriterSettings?).

-
BufferedStream and StreamWriter classes (even Stream class to some degree) cache data internally. I suggest you use either of those classes instead of building and maintaining your own cache. Edit: Actually, FileStream already has an internal buffer, so there is no point in using BufferedStream either. It will only result in double buffering.

-
I did not quite understand what projection is, so I'm not sure if it's really needed, but in my experience - passing a delegate to a constructor (let alone a collection of delegates) is almost always a bad idea. :)

Code Snippets

public IEnumerable<char> IgnoredCharacters
    {
        get
        {
            return this.ignoredCharacters;
        }
    }

Context

StackExchange Code Review Q#69829, answer score: 5

Revisions (0)

No revisions yet.