Необходимо написать приложение транслятор - приложение которое читает файл и на основе определенных критерий формирует выходной файл нужной структуры и нужным набором полей.
На входе имеем директорию с набором текстовых файлов, на выходе должны получить набор необходимых файлов.
Приложение должно иметь конфигурационный файл в котором задаются:
- Маска имени файла для разбора
- Разделители строк и колонок входного файла
- Фильтр для строк, какие строки нужно разбирать
- Конфигурация какие колонки необходимо использовать для выходного файла
- Разделители строк и колонок выходного файла
- Именование выходного файла
- Использовать исходное имя
- Использовать исходное имя + префикс
- Использовать своё имя с инкриментом для каждого нового файла
- Указывается входная директория в которую поступают файлы
- Указывается выходная директория куда поступают файлы после трансляции Приложение не должно проводить повторную трансляцию файла если он уже был ранее обработан.
Скомпилированное приложение и необходимые для работы конфигурационный файлы находятся в директории build
:
config
- директория с настройкамиconfig.xml
- настройки приложенияlog4j2.xml
- настройки логирования
in
- директория входных файловout
- директория выходных файлов. При отсутствии создается при экспорте файловarchive
- директория архивных файлов. При отсутствии создается при архивировании файловfileparser.jar
- исполняемый файл приложенияrun.bat
- файл для запуска приложения на Windowsinput_1.csv
- тестовый файл для преобразования
Для запуска на Windows необходимо запустить файл run.bat
Приложение представляет собой консольную утилиту.
При запуске считывается конфигурация из файла config.xml
и хранится в экземпляре singleton класса Configuration
После запуска в отдельном потоке стартует экземпляр ProcessorRunner
,
который с определенной периодичностью запускает обработку файлов с помощью экземпляра DelimitedFileProcessor
.
DelimitedFileProcessor
занимается чтением файлов и построчной обработкой каждого файла,
после завершения которой файл переносится в архивную папку.
При создании DelimitedFileProcessor
инициализируется его настройки в экземпляре DelimitedProcessorConfig
,
который содержит настройки входных, выходных и архивных файлов, а также настройки колонок в строке.
В начале обработки считывается список файлов из заданной входной директории.
К каждому из обнаруженных файлов применяется фильтр InputFileFilter
,
задача которого - определить соответствует ли имя файла в директории заданному glob-шаблону.
Для каждого файла производится построчная обработка с проверкой каждой строки посредством RegexLineFilter
на удовлетворение шаблону строки из настроек.
Построчным парсингом и экспортом файлов занимаются соответственно:
DelimitedParser
- разбивает переданную строку по regexp-шаблону с заданным разделителем.DelimitedExporter
- формирует строку с колонками, которые отмечены в настройках как эспортируемые, и заданными разделителями. С помощью переданного при создании writer сохраняет сформированную строку в файл.
При создании DelimitedExporter
формируется путь к эспортируемому файлу, состоящий из:
- пути к директории выходных файлов, заданному в настройках
- имени выходного файла, шаблон которого задан в настройках.
Шаблон имени выходного и архивного файлов может содержать произвольный текст и преднастроенные элементы, что позволяет формировать имя файла, не ограничиваясь указанными в Задании вариантами (н-р, out-{INPUT_NAME}-{SEQ}-{TIME}.txt)
{INPUT_NAME}
- имя входного файла{INPUT_EXT}
- расширение входного файла (для архивных файлов){SEQ}
- инкремент файла с начала работы программы{DATE}
- текущая дата (yyyy-mm-dd){TIME}
- текущее время (HH_mm_ss){DATE_TIME}
- текущие дата и время (yyyy-mm-dd_HH_mm_ss)
В настройках config.xml
также описываются колонки входного файла config.processors.delimiterProcessor.columns
.
Данная настройка нужна для определения порядка колонок и проставления флага необходимости экспорта для отдельных колонок.
Например:
<columns>
<column exported="true">Date</column>
<column exported="true">Time</column>
<column>Col 3</column>
<column>Col 4</column>
</columns>
Для экспорта колонки, должны быть описаны все предшествуюшие ей колонки.