Как читать текстовые файлы, в которых смешаны перевод строки и возврат каретки с использованием X ?

#axapta #dynamics-ax-2009 #ax

#axapta #dynamics-ax-2009 #ax

Вопрос:

Я пытаюсь прочитать текстовый файл с помощью Dynamics AX. Однако следующий код заменяет любые пробелы в строках запятыми:

 // Open file for read access
myFile = new TextIo(fileName , 'R');

myFile.inFieldDelimiter('n');

fileRecord = myFile.read();
while (fileRecord)
{
    line = con2str(fileRecord);
    info(line);
…
  

Я пробовал различные комбинации приведенного выше кода, включая указание пустого '' разделителя полей, но с тем же поведением.

Следующий код работает, но, похоже, должен быть лучший способ сделать это:

 // Open file for read access
myFile = new TextIo(fileName , 'R');

myFile.inRecordDelimiter('n');
myFile.inFieldDelimiter('_stringnotinfile_');

fileRecord = myFile.read();
while (fileRecord)
{
    line = con2str(fileRecord);
    info(line);
  

Формат файла — это формат поля. Например:

 DATAFIELD1    DATAFIELD2  DATAFIELD3
DATAFIELD1                DATAFIELD3
DATAFIELD1    DATAFIELD2  DATAFIELD3
  

Итак, в итоге я получаю, если не использую описанный выше обходной путь, что-то вроде:

 line=DATAFIELD1,DATAFIELD2,DATAFIELD3
  

Основная проблема здесь в том, что у меня смешанные форматы ввода. В некоторых файлах есть только перевод строки {LF} , а в других есть {CR}{LF} . Использование моего обходного пути, описанного выше, похоже, работает для обоих. Есть ли способ справиться с обоими или удалить r из файла?

Ответ №1:

Con2Str:

Con2Str извлекает список значений из контейнера и по умолчанию использует comma (,) для разделения значений.

 client server public static str Con2Str(container c, [str sep])
  

Если для sep параметра не указано значение, символ запятой будет вставлен между элементами в возвращаемой строке.

Возможные варианты:

  1. Если вы хотите, чтобы пробел был разделителем по умолчанию, вы можете передать пробел в качестве второго параметра в метод Con2Str .

  2. Еще один вариант заключается в том, что вы также можете перебирать содержимое контейнера fileRecord для извлечения отдельных элементов.

Фрагмент кода 1:

Приведенный ниже фрагмент кода загружает содержимое файла в textbuffer и заменяет символы возврата каретки ( r ) символом новой строки ( n ). Условие if (strlen(line) > 1) поможет пропустить пустые строки из-за возможного появления последовательных символов новой строки.

 TextBuffer  textBuffer;
str         textString;
str         clearText;
int         newLinePos;
str         line;
str         field1;
str         field2;
str         field3;
counter     row;
;

textBuffer  = new TextBuffer();
textBuffer.fromFile(@"C:tempInput.txt");
textString  = textBuffer.getText();
clearText   = strreplace(textString, 'r', 'n');

row = 0;
while (strlen(clearText) > 0 )
{
    row  ;
    newLinePos  = strfind(clearText, 'n', 1, strlen(clearText));
    line        = (newLinePos == 0 ? clearText : substr(clearText, 1, newLinePos));

    if (strlen(line) > 1)
    {
        field1  = substr(line, 1, 14);
        field2  = substr(line, 15, 12);
        field3  = substr(line, 27, 10);

        info('Row '   int2str(row)   ', Column 1: '   field1);
        info('Row '   int2str(row)   ', Column 2: '   field2);
        info('Row '   int2str(row)   ', Column 3: '   field3);
    }

    clearText =  (newLinePos == 0 ? '' : substr(clearText, newLinePos   1, strlen(clearText) - newLinePos));
}
  

Фрагмент кода 2:

Вы могли бы использовать файловый макрос вместо жесткого кодирования значений rn и R , который обозначает режим чтения.

 TextIo      inputFile;
container   fileRecord;
str         line;
str         field1;
str         field2;
str         field3;
counter     row;
;

inputFile = new TextIo(@"c:tempInput.txt", 'R');

inputFile.inFieldDelimiter("rn");

row = 0;
while (inputFile.status() == IO_Status::Ok)
{
    row  ;
    fileRecord  = inputFile.read();
    line        = con2str(fileRecord);

    if (line != '')
    {
        field1  = substr(line, 1, 14);
        field2  = substr(line, 15, 12);
        field3  = substr(line, 27, 10);

        info('Row '   int2str(row)   ', Column 1: '   field1);
        info('Row '   int2str(row)   ', Column 2: '   field2);
        info('Row '   int2str(row)   ', Column 3: '   field3);
    }
}
  

Вывод задания Dynamics AX

Комментарии:

1. Это помогло мне определить проблему — некоторые текстовые файлы, которые я читаю, имеют r n, а некоторые просто n. Смотрите последнюю правку.

Ответ №2:

Никогда не пробовал использовать параметр RecordDelimiter по умолчанию в качестве FieldDelimiter и не устанавливал явно другой параметр RecordDelimiter. Обычно строки (записи) разделяются символом n, а поля разделяются запятой, табуляцией, точкой с запятой или каким-либо другим символом. Вы также можете столкнуться с некоторым странным поведением, когда TextIO принимает правильный UTF-формат. Вы не предоставили пример некоторых строк из вашего файла данных, поэтому угадать сложно.

Подробнее о TextIO читайте здесь: http://msdn.microsoft.com/en-us/library/aa603840.aspx

Редактировать: Что касается дополнительного примера содержимого файла, мне кажется, что файл представляет собой файл фиксированной ширины, где каждый столбец имеет свою собственную фиксированную ширину. Я бы скорее рекомендовал использовать subStr, если это так. Прочитайте о substr здесь:http://msdn.microsoft.com/en-us/library/aa677836.aspx

Комментарии:

1. Извините, вы правы — я не предоставил подробную информацию о файле. Пожалуйста, посмотрите последнюю правку.

Ответ №3:

используйте StrAlpha для ограничения пустых значений после преобразования Con2Str