Запись записей переменной длины в файл с помощью FileHelper?

Я использую FileHelper записывать записи в плоский файл. Первые 20 полей этих записей являются фиксированными, если значения пусты, пробелы будут заполнены. В то время как последние 4 поля являются необязательными, если они все пусты, эти позиции не должны быть заполнены пробелами. Но FileHelper продолжайте заполнять эти позиции пробелами.

Можно ли добиться этого, используя FileHelper?

[FixedLengthRecord(FixedMode.AllowVariableLength)] 
public class MyReport
{
    [FieldFixedLength(2)]
    public string field1;

    [FieldFixedLength(10)] 
    public string field2;
    ...
    [FieldFixedLength(96)] 
    [FieldOptional]
    public string field32;

    [FieldFixedLength(96)]
    [FieldOptional]
    public string field33;

    [FieldFixedLength(96)]
    [FieldOptional]
    public string field34;

    [FieldFixedLength(96)]
    [FieldOptional]
    public string field35;
}

2 ответа

Я подозреваю, что это произойдет, потому что у вас есть атрибут FixedLength() в каждом из необязательных полей. Необязательный атрибут, насколько мне известно, действительно отображается только при импорте, поэтому при отсутствии значения (null) ничего не устанавливается.

Подтверждение этому можно найти здесь: http://www.filehelpers.net/docs/html/T_FileHelpers_FieldOptionalAttribute.htm

Учитывая то, что вы пытаетесь сделать, я думаю, вам нужно написать собственный конвертер, который бы справился с этим для вас и убрал бы атрибут fixedwidth.

public sealed class FixedWidth96Converter : ConverterBase
{
    public override string FieldToString(object from)
    {
        string val = from as string;
        if (!string.IsNullOrWhiteSpace(val))
        {
            return val.PadLeft(96, ' ');
        }
        return base.FieldToString(from);
    }

    public override object StringToField(string from)
    {
        return from;
    }
}

Вы можете удалить любые дополнительные разделители в AfterWriteRecord событие

Вот рабочий пример:

[DelimitedRecord(",")]
public partial class Person
{
    public string FirstName;
    public string LastName;
    [FieldOptional]
    public string Optional1;
    [FieldOptional]
    public string Optional2;
    [FieldOptional]
    public string Optional3;
}      

class Program
{
    private static void Main(string[] args)
    {
        var engine = new FileHelperEngine<Person>();
        engine.AfterWriteRecord += engine_AfterWriteRecord;
        var export = engine.WriteString(
                     new Person[] { 
                       new Person() { FirstName = "Joe", LastName = "Bloggs" } 
                     });
        Assert.AreEqual("Joe,Bloggs" + Environment.NewLine, export);
    }

    static void engine_AfterWriteRecord(EngineBase engine, AfterWriteEventArgs<Person> e)
    {
        // trim trailing empty separators
        e.RecordLine = e.RecordLine.TrimEnd(',');
    }
}
Другие вопросы по тегам