2010-12-04 3 views
5

У меня есть один файл csv, который записывается непрерывно по сценарию. Он записывает метку времени и некоторые другие данные в строке. Сначала я должен прочитать последние данные. В настоящее время я использую RandomAccessFile в java для чтения файла в обратном порядке. Но поскольку он написан постоянно, я должен прочитать новые данные с приоритетом. Я поддерживаю, какая временная метка отправлена ​​и выполняет работу. Это приводит к ненужным действиям сканирования.Нужно предложение по моему подходу: читать файл, который записывается непрерывно?

Есть ли лучший способ справиться с этим сценарием?

Спасибо заранее,

ответ

1

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

В зависимости от того, сколько времени требуется для обработки новой строки по сравнению с тем, как быстро они сгенерированы, этого может быть достаточно. Если новые строки генерируются быстрее, чем вы можете их обработать, то этот подход, вероятно, не сработает - стек станет слишком большим, и у вас закончится нехватка памяти. В этом случае, в зависимости от ваших требований, вы можете уйти с ограниченным размером стеком, который отбрасывает старые записи.

1

Две идеи:

  1. Используйте фиксированный размер формат записи вместо CSV. Затем вы можете точно указать, что заставляет ваши записи вместо того, чтобы искать вокруг новых строк.

  2. Если это невозможно, укажите поток, который считывает элементы из файла и выталкивает их в стек. Другой поток выталкивает элементы из стека и обрабатывает их. Поскольку это стек, он всегда будет иметь дело с последним доступным элементом. Вам нужно выяснить, как вы хотите иметь дело с случаями, когда стек становится слишком большим. Вы просто хотите выбросить слишком старые предметы?

0

Если у вас есть доступ к исходному сценарию, напишите запись в базу данных в дополнение к CSV-файлу. Затем вы можете делать все, что хотите, с базой данных; доступ к последней записи, запуск отчета и т. д.

0

Это приводит к ненужным действиям сканирования.

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

я могу думать о трех способов сделать это, что может быть более эффективным, чем то, что вы сейчас делаете:

  1. Читать весь файл и разобрать строки в форварды направлении, сохраняя свои позиции в памяти , Затем обрабатывайте строки в памяти в обратном порядке.

  2. Сканирование файла с начала поиска начала строки и сохранение начальных позиций строки в памяти. Затем перебирайте позиции в обратном порядке, пытаясь каждому прочитать строку. (Вы можете сделать ввод более эффективно, обрабатывая несколько строк в каждом поиске.)

  3. Составьте файл в память с помощью MappedByteBuffer, затем вы можете пройти через буфер байтов вперед или назад, чтобы найти границы строк.

Первый подход требует, чтобы вы буфер весь файл в памяти, но имеет более низкие накладные расходы I/O, потому что вы читаете файл только один раз с минимальным количеством системных вызовов. Третий подход имеет ту же самую проблему, хотя вы можете сопоставить чрезвычайно большой файл в памяти в больших (больших) разделах, чтобы уменьшить требования к памяти.

Но, в конечном счете, нет простого и эффективного способа чтения файла на Java.

0

Если ваше приложение работает в среде Unix, вы можете запустить

tail -f /csv-file | custom-program 

пользовательскую программу обработки будет просто принимать стандартный ввод и эхо, что сокет-соединение с вашей программой Java.

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

Смежные вопросы