Запись записей переменной длины в файл с помощью 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;
}

person vijay    schedule 21.01.2013    source источник
comment
есть ли способ добавить условные операторы с помощью FileHelpers..?   -  person MethodMan    schedule 21.01.2013


Ответы (2)


Вы можете удалить лишние разделители в событии 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(',');
    }
}
person shamp00    schedule 21.03.2013
comment
Для людей, которые смотрят на это и думают, что обычные соглашения об именах предполагают, что это должно быть BeforeWrite, а не AfterWrite, код фактически вызывает BeforeWrite, затем преобразует поля в одну строку текста, вызывает AfterWrite и затем фактически записывает текст. Не существует истинного события после записи данных в файл, а AfterWrite действительно является событием Pre-write. - person netniV; 10.09.2015

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

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

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

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;
    }
}
person netniV    schedule 09.08.2015
comment
Я бы согласился с оператором FieldOptional, потому что при записи ваши заголовки столбцов должны соответствовать данным, а поскольку FileHelpers не будет знать, что все столбцы пусты, пока он не обработает все поля, у него нет общего способа сделать это. Вы можете удалить поля с помощью функции .RemoveField(), но вы удалите это поле из ВСЕХ строк, а не только из одной. - person netniV; 10.09.2015