Торгові роботи - файлові операції з масивами і колекціями

У процесі створення програм на мові QPILE нерідко виникає завдання збереження будь-яких змінних на диску. Це необхідно, наприклад, при обміні даними між різними портфелями або при збереженні інформації між послідовними ітераціями одного портфеля.

Найпростіший шлях, що приходить в голову з урахуванням небагатого потенціалу мови QPILE - це зберегти через підрядник все дані в зовнішньому файлі, наприклад, по одному значенню в рядку або в один рядок, розділивши значення комами, отримавши по суті формат даних CSV. Після чого, знаючи послідовність, в якій дані були збережені, можна їх прочитати з файлу збереження і розпізнати.

Дуже клопітно, вихідний текст розбухає на очах. Але найголовніше - спосіб не універсальний. Кожен раз доведеться писати дві досить об'ємні функції, одна з яких в потрібному порядку зберігає дані, інша в тому ж порядку їх зчитує. Змінивши щось в одній, доведеться обов'язково виправляти другу. Одного разу пройшовши через таку процедуру, вирішив написати універсальний механізм для майбутнього використання.

Як відомо, все агрегатні дані в QPILE - масиви ії колекції фактично являють собою рядки. Чому б просто не зберігати дані цих типів як рядки? Найпростіший тест - створюємо асоціативний масив, пишемо його в файл, потім читаємо з файлу і порівнюємо з оригінальним. Результат - збігаються. Для колекції результат не менше позитивний (з чого б йому таким не бути?).

Функції були написані. У процесі використання з'ясувалася проблема. Справа в тому, що з QPILE можна записати в файл рядок (практично) будь-якої довжини, а ось прочитати можна тільки 1 кілобайт. Чому? Таке природне властивість інтерпретатора - питання до разбработчікам. Доведеться і це обмеження обійти шляхом розбиття довжини рядка на частини. В результаті ось пара функцій:

'' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' ''
"Збереження колекції або асоціативного масиву в файл
'Подолання обмеження qpile на 1000 символів в одному рядку
'При успішному завершенні повертається порожній рядок, при помилці рядок з діагностикою системи
FUNC Save_Object (so_FileName, so_Object)
clear_file (so_FileName)
for so_count from 0 to len (so_Object) - 1
result = writeln (so_fileName, substr (so_Object, so_count 1000))
if 0 + get_value (result, "RESULT") = 0
result = get_value (result, "DESCRIPTION")
return
end if
so_count = so_count + 999
end for
result = ""
END FUNC

'' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' ''
'Читання об'єкта з файлу. Повертає асоціативний масив
'RESULT - вміст файлу (об'єкт)
'ERROR - код помилки. 0 - успішно, 1 - помилка
FUNC Read_Object (ro_FileName)
ro_string = ""
result = 0
ro_size = get_file_len (ro_FileName)
for so_count from 1 to ro_size
ro_string = ro_string read_line (ro_FileName, so_count, result)
if result> 0
result = set_value (create_map (), "ERROR", result)
return
end if
end for
result = set_value (create_map (), "RESULT", ro_string)
END FUNC