Как читать текстовые файлы, в которых перевод строки и возврат каретки смешаны с использованием X ++? - PullRequest
1 голос
/ 24 мая 2011

Я пытаюсь прочитать текстовый файл с помощью 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 из файла?

Ответы [ 3 ]

3 голосов
/ 25 мая 2011

Con2Str:

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

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

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

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

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

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

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

Ниже фрагмент кода загружает содержимое файла в текстовый буфер и заменяет возврат каретки (\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:\temp\Input.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:

Вы можете использовать File macro вместо жесткого кодирования значений \r\n и R, которые обозначают режим чтения.

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

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

inputFile.inFieldDelimiter("\r\n");

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 job output

1 голос
/ 24 мая 2011

Никогда не пытался использовать 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

0 голосов
/ 12 апреля 2016

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

...