![]() |
Модераторы: LSD, AntonSaburov |
![]() ![]() ![]() |
|
Stampede |
|
|||
![]() Гносеолог ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 963 Регистрация: 25.4.2005 Где: Calgary, Alberta, Canada Репутация: 24 Всего: 144 |
Взываю к коллективной мудрости.
Имеется задача: есть текстовые документы некоего фиксированного формата (финансовые отчеты). Их нужно парсить: определять по заданным признакам начало и конец отдельного документа (например, инвойса), а затем внутри документа выделять, опять же по заданным признакам, определенные поля (номер счета, сумму, дату и пр.), и вытягивать их значения. Потом вся эта выуженная информация куда-нибудь сохраняется. Признаки наяала и конца документа, а также отдельных его полей, задаются в виде регулярных выражений. Если бы можно было зачитать весь файл целиком в память, то всех делов было бы примерно минут на пять ![]() То есть я вижу себе такое как бы ползущее окно, которое двигается вдоль файла и сканирует его на предмет начала/конца документа. Когда документ полностью детектирован, мы проходим по нему второй раз и определяем значения полей. Тут, казалось бы, тоже нет ничего трудного, но есть ряд нюансов. Во-первых, побуферный парсинг здесь не подходит, так как искомая строка может оказаться разорванной на границе буфера, и регекспом не обнаружится. Во-вторых, даже один отдельный документ может быть достаточно большим, поэтому и внутри него парсить нужно будет тоже не в памяти. Из хороших моментов: известно, что искомая строка не может перекрывать раздел страниц, то есть можно безопасно ориентироваться на символ конца страницы как на сигнал к закрытию текущего буфера. Впоследствии этот же механизм ползущего окна хотелось бы использовать в гуевом приложении для отображения файла в окне прокрутки без загрузки в память целиком. На ум приходит что-то вроде смапленной на файл виртуальной строки (условно) бесконечной длины, но как это лучше реализовать - пока не соображу. У кого какие будут идеи? ЗЫ. Блин, ошибся топиком. Прошу перенести в Java: Общие вопросы. Спасибо. Это сообщение отредактировал(а) Stampede - 28.4.2005, 01:26 -------------------- "If you want something done right, do it yourself" По секрету: выучить английский - реально! |
|||
|
||||
Domestic Cat |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5452 Регистрация: 3.5.2004 Где: Dallas, US Репутация: 50 Всего: 172 |
Может этим:
http://java.sun.com/j2se/1.4.2/docs/api/ja...ByteBuffer.html правда дальше я не думал, но вроде как подходит, есть asCharBuffer и проч. -------------------- |
|||
|
||||
Zandr |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 433 Регистрация: 16.7.2004 Где: Новосибирск Репутация: 9 Всего: 13 |
Если регекспы, то обрати внимание, что они ищут не в String'ах или StringBuffer'ах, а в CharSequence. CharSequece это интерфейс. Можешь попробовать реализовать что-нить типа:
На счет быстродействия ничего сказать не могу - как реализуешь. Это сообщение отредактировал(а) Zandr - 28.4.2005, 09:43 |
|||
|
||||
Stampede |
|
|||
![]() Гносеолог ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 963 Регистрация: 25.4.2005 Где: Calgary, Alberta, Canada Репутация: 24 Всего: 144 |
Котъ, Zandr - спасибо за идеи. Будет чем заняться завтра на работе
![]() -------------------- "If you want something done right, do it yourself" По секрету: выучить английский - реально! |
|||
|
||||
Stampede |
|
|||
![]() Гносеолог ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 963 Регистрация: 25.4.2005 Где: Calgary, Alberta, Canada Репутация: 24 Всего: 144 |
Докладаю.
Сижу и тащусь как удав по пачке дуста. Работает - проооосто как песТня. Всего делов было - несколько строк преобразований типа RandomAccessFile -> FileChannel -> MappedByteBuffer -> (Charset, CharsetDecoder) -> CharBuffer. Фсе! Далее абстрагируемся от подлежащего (underlying) файла и регекспим как обычную строку! Спасибо, отцы! Да здравствует Винградовка! ![]() ЗЫ. Хотел не радостях вам плюсов надавать - не пущает. Маладой, говорит, ишшо. Это я-то молодой? Хе-хе ... Котъ, ну хоть Zandr'у влепи одного - от имени, тыкскыть, и по поручению благодарной общественности ![]() Это сообщение отредактировал(а) Stampede - 29.4.2005, 01:10 -------------------- "If you want something done right, do it yourself" По секрету: выучить английский - реально! |
|||
|
||||
Domestic Cat |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5452 Регистрация: 3.5.2004 Где: Dallas, US Репутация: 50 Всего: 172 |
Ура так сказать! Тащимся вместе с тобой !
![]() ![]() ![]() -------------------- |
|||
|
||||
Zandr |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 433 Регистрация: 16.7.2004 Где: Новосибирск Репутация: 9 Всего: 13 |
Красиво ![]() |
|||
|
||||
Stampede |
|
|||
![]() Гносеолог ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 963 Регистрация: 25.4.2005 Где: Calgary, Alberta, Canada Репутация: 24 Всего: 144 |
Любознательным на заметку, дополнение:
Красиво-то оно может и красиво, но я вот сейчас попробовал получить буфер напрямую, без преобразований через CharDecoder - через метод asCharBuffer(), который предлагал Котъ, так оно теперь в 5 (пять!) раз быстрее мослает. Но, блин, нет в мире совершенства. Это работает только с текстами в ASCII. Если нужна другая кодировка, придется все равно использовать CharDecoder. А что делать? Да, кстати, с седьмым плюсом тебя? ![]() |
|||
|
||||
Stampede |
|
|||
![]() Гносеолог ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 963 Регистрация: 25.4.2005 Где: Calgary, Alberta, Canada Репутация: 24 Всего: 144 |
Блин, погорячился. Вношу поправку.
Короче, по производительности никакого выигрыша почти нет. Просто я не заметил, что в варианте с asCharBuffer() содержимое интерпретировалось неправильно, поэтому регекспы ничего не находили, и в результате получалось быстрее. Нам, однако, такой хоккей не нужен. Нам нужно не быстро, а нам нужно, чтобы правильно. Так вот, в ходе экспериментов выяснилось, что по дефолту тот буфер, который возвращает asCharBuffer() (какой-то внутренний класс DirectByteBuffer), поддерживает только кодировку UTF-16. Скорость обработки файла при этом сопостовима со скоростью в варианте с CharsetDecoder (правда, там сам исходный файл в UTF-16 в два раза длиннее, так что вроде бы работает быстрее, но нам ведь нужно ехать, а не шашечки ![]() Поиски способа сменить дефолтную кодировку ни к чему не привели, так что, как говорится, не выеживайтесь, Иван Иваныч, слушайте вашу любимую песню "Валенки" ![]() На случай, если у кого-то возникнет аналогичная задача, привожу код манипуляций:
Это сообщение отредактировал(а) Stampede - 30.4.2005, 17:22 -------------------- "If you want something done right, do it yourself" По секрету: выучить английский - реально! |
|||
|
||||
Zandr |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 433 Регистрация: 16.7.2004 Где: Новосибирск Репутация: 9 Всего: 13 |
Вот не совсем понятное место:
Не прошарил как работает этот метод... Он не пытается сразу весь файл перекачать в память? Или как задумано дает char'ы что называется on demand? |
|||
|
||||
![]() ![]() ![]() |
Правила форума "Java" | |
|
Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, LSD, AntonSaburov, powerOn, tux, javastic. |
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | Java: Общие вопросы | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |