ЧтениеДанных.ПрочитатьСтроку() некорректное поведение
Опишите ошибку Функция ЧтениеДанных.ПрочитатьСтроку некорректно извлекает строки из двоичных данных
Воспроизведение ошибки
- Запустить код
ДвДанные = ПолучитьДвоичныеДанныеИзHexСтроки("31 32 33 0d 0a 34 35 36");
Чтение = Новый ЧтениеДанных(ДвДанные);
лСтрока = Чтение.ПрочитатьСтроку();
лПозиция = Чтение.ИсходныйПоток().ТекущаяПозиция();
Сообщить("Прочитана строка: " + лСтрока);
Сообщить("Текущая позиция чтения потока: " + лПозиция);
лСтрока = Чтение.ПрочитатьСтроку();
лПозиция = Чтение.ИсходныйПоток().ТекущаяПозиция();
Сообщить("Прочитана строка: " + лСтрока);
Сообщить("Текущая позиция чтения потока: " + лПозиция);
Чтение.Закрыть();
- Результат выполнения кода
Прочитана строка: 123
Текущая позиция чтения потока: 8
Прочитана строка:
Текущая позиция чтения потока: 8
Ожидаемый результат выполнения кода
Прочитана строка: 123
Текущая позиция чтения потока: 5
Прочитана строка: 456
Текущая позиция чтения потока: 8
Окружение
- ОС: Win 10 pro 1909
- Версия: oscript 1.7.0
Дополнительная информация Функция ЧтениеДанных.ПрочитатьСтроку при первом вызове корректно определяет позицию окончания первой строки корректно извлекает и возвращает первую строку НО после вызова текущая позиция чтения потока оказывается в конце потока и следующий вызов уже ничего не возвращает В 1С этот код отрабатывает как ожидается
По документации, если в конструкторе ЧтениеДанных не указан разделитель строк, то его значение по умолчанию Неопределено, что даёт после инициализации РазделительСтрок="". Соответственно, КонвертируемыйРазделительСтрок по умолчанию равен "\r\n".
Тогда в приведённом примере прочитанная строка должна быть "123\n456", а позиция в потоке = 8.
Получается, что неправы оба: и Onescript, и 1С.
Onescript читает первую строку как "123\r". Там ошибочно по умолчанию РазделительСтрок = "\n". Поток читается до конца.
В 1С согласно описанию будет РазделительСтрок = "". Но в случае, когда разделитель строк - пустая строка (в т. ч. явно заданная через параметр!) как разделитель будет использована любая найденная из строк "\r", "\n","\r\n". Ошибка или в документации, или в реализации.
КонвертируемыйРазделительСтрок по умолчанию равен "\r\n". Это байты 0d 0a, что вы видите в приведенном примере на позициях 3 и 4. 1С отработал корректно и документация в порядке. Onescript работает странно. Если он прочитал поток до конца, то и выводил бы содержимое всего потока. Если он прочитал только до символа \n, то позиция должна остаться 5, чтобы была возможность чтения следующей строки.
Странность работы Onescript подтверждается. Но, для уточнения корректности документации и работы 1С, пример. Согласно имеющемуся описанию, какие строки должны быть прочитаны и каковы будут при этом позиции в потоке для такого варианта:
ДвДанные = ПолучитьДвоичныеДанныеИзHexСтроки("0a 0a 0d 0a 0d 0d 0d 0a");
Чтение = Новый ЧтениеДанных(ДвДанные,,, "",""); // оба разделителя - пустые строки
Пока Не Чтение.ЧтениеЗавершено Цикл
лСтрока = Чтение.ПрочитатьСтроку();
лПозиция = Чтение.ИсходныйПоток().ТекущаяПозиция();
Сообщить("Прочитана строка '" + лСтрока+"' длины "+СтрДлина(лСтрока));
Сообщить("Текущая позиция чтения потока: " + лПозиция);
КонецЦикла;
Чтение.Закрыть();
?
АПИ работы с двоичными данными в 1Скрипт появилось довольно поздно, поскольку в 1С его вообще не было никакого. Подводные камни и нюансы работы 1С с ЧтениемДанных никем досконально не исследовались, в силу отсутствия опыта работы с ЧтениемДанных (его не было ни у кого на момент выхода этого АПИ). @ilyabaztard если вы окажете нам помощь и зафиксируете требования к правильному поведению - мы будем вам признательны. А за исправление вообще расцелуем и обнимем
Попробую для начала доработать тесты под этот случай
@ilyabaztard есть успехи?
ЧтениеДанных, по-видимому, унаследовало параметры РазделительСтрок и КонвертируемыйРазделительСтрок от объекта ЧтениеТекста. Но работа с ними: значения по умолчанию и порядок применения - существенно различаются.
Функции ЧтениеДанных.ПрочитатьСтроку() и ЧтениеТекста.ПрочитатьСтроку() могут давать разный результат на одинаковых входных данных с одинаковыми (в том числе явно указанными) параметрами.