Тема: VBS : подскажите как - Построчное чтение текстовых файлов с конца
Построчное чтение текстовых файлов с конца
Вы не вошли. Пожалуйста, войдите или зарегистрируйтесь.
Серый форум → Общение → Windows Script Host, HTA (VBScript, JScript) → VBS : подскажите как - Построчное чтение текстовых файлов с конца
Страницы 1
Чтобы отправить ответ, вы должны войти или зарегистрироваться
Построчное чтение текстовых файлов с конца
Построчное чтение текстовых файлов с конца
Если формат файла представляет собой так называемый обычный текст, и его размер не превышает 10 МБ, то самый простой способ заключается в следующем:
- с помощью метода ReadAll модели FSO прочитать текст в переменную;
- с помощью функции Split() преобразовать значение этой переменной в массив, используя в качестве символа-разделителя строк значение vbNewLine;
- в цикле прочитать нужное количество строк, начиная с конца полученного массива.
Если ситуация иная, то нужно указать тип файла и его размер.
2 Dmitrii > откуда такие установки - 10MB ?
То , о чем Вы сказали, не подразумевает построчное чтение, а подразумевает чтение ЦЕЛИКОМ.
Тип файла указан - текстовый, с разбитием на строки символами VbCrLf , размер,раз не указан,то значит, естественно - любой разумный размер (ну или по усмотрению разработчика идеи) .
kefi
Откуда такие установки - "любой разумный размер"?
Чем разумный размер отличается от неразумного?
... откуда такие установки - 10MB ?..
Из суммы опыта сообщества участников данного форума и личного опыта.
... То , о чем Вы сказали, не подразумевает построчное чтение, а подразумевает чтение ЦЕЛИКОМ...
Чтение целиком выполняется как раз для того, чтобы получить возможность чтения строк в обратной последовательности. Коль скоро Вас не устраивает такой способ, могу посоветовать следующее:
- открыть файл в каком-либо приложении, поддерживающем средства Automation (скажем, в MS Word);
- читать нужные строки в нужном порядке, обращаясь из сценария к элементам объектной модели приложения.
Если и этот вариант не подходит, то Вам прямой путь к средствам организации произвольного доступа к файлу либо непосредственно с помощью функций WinAPI, либо опять-таки с помощью средств какого-нибудь приложения.
Впрочем, здесь, если мне не изменяет память, Вы столкнётесь с одним ограничением - при произвольном доступе чтение выполняется не построчно, а поблочно или побайтово. Следовательно, придётся решать задачу идентификации начала и конца строки.
... Тип файла указан - текстовый, с разбитием на строки символами VbCrLf , размер,раз не указан,то значит, естественно - любой разумный размер (ну или по усмотрению разработчика идеи) .
Если Вы считаете, что сделанное Вами в исходном сообщении темы описание задачи носит исчерпывающий характер, то Вы ошибаетесь.
2 Dmitrii >
Спасибо за идеи, насчет Automation - пока не могу априори оценить затраты(в смысле занимаемой памяти/временных издержек), но интересно (т.к. не приходило в голову).
Насчет прямого доступа - понятно.
Но вот , что не понятно, так это то, что вообще говоря, ни один из этих способов не подразумевает опять же построчного чтения - первый считывает ВЕСЬ файл в память, второй кусками, но не строками.
Т.е. - я хотел выяснить , вообще построчное чтение с конца файла возможно или нет , в таком виде ,как оно делается с начала, например,
Set fso = CreateObject("Scripting.FileSystemObject")
Set tsLog = fso.OpenTextFile(LogFileName, ForReading)
Do While Not tsLog.AtEndOfStream
LineInFile = tsLog.ReadLine
LoopЯ так понял - что ответ отрицательный (в смысле такое невозможно)?
Если Вы считаете, что сделанное Вами в исходном сообщении темы описание задачи носит исчерпывающий характер, то Вы ошибаетесь.
Я никогда не считаю, что можно исчерпывающе описать задачу, тем более на Inet-форуме, где всегда можно придраться и показать, что ты что-то упустил. Я считаю, что можно достаточно понятно объяснить задачу, при желании читающих понять .
... Т.е. - я хотел выяснить , вообще построчное чтение с конца файла возможно или нет , в таком виде ,как оно делается с начала...
При такой постановке вопроса ответ однозначно отрицательный.
kefi, работа с файлами последовательного доступа не предполагает никакой другой работы, кроме как чтения построчно от начала к концу. Все прочие методы работы с такими файлами так или иначе инкапсулируют именно этот единственный механизм.
от начала к концу
А чем конец хуже начала. Разве тем, что записи туда добавляются, но ведь необязательно, что в момент, когда я хочу последовательно читать с конца, файл будет обновляться, поэтому - почему бы было бы не сделать системные инструменты, позволяющие читать ( в монопольном режиме хотя бы ) текстовые файлы построчно с конца .
от начала к концу
А чем конец хуже начала. Разве тем, что записи туда добавляются, но ведь необязательно, что в момент, когда я хочу последовательно читать с конца, файл будет обновляться, поэтому - почему бы было бы не сделать системные инструменты, позволяющие читать ( в монопольном режиме хотя бы ) текстовые файлы построчно с конца .
kefi,
файлы хранятся в виде последовательно связанных кусков - кластеров. И эти кластеры - для любого конкретного файла - хаотически разбросаны по всему винчестеру.
Открывая файл Вы обращаетесь к каталогу, в котором известен только самый первый кластер данного файла.
Прочитав первый кластер, в его конце Вы узнаете где находится второй.
Прочитав второй - узнаете где лежит третий. И т.д.
Конец ничем не хуже начала - просто чтобы узнать где он надо пройти по всей цепочке.
Чтобы реализовать Вашу идею нужны не "системные инструменты", а принципиально иная организация файловой системы. Чтобы в каждом кластере была ссылка не только на последующий, но и на предыдущий.
Да и в каталоге тогда нужно каждому файлу сопоставлять не первый, а коллекцию всех его кластеров. Чтобы уж совсем читать с любого места и в любом направлении.
А то ведь захочется читать и с середины. А чем середина хуже конца? ![]()
На самом деле такие инструменты уже давно существуют - базы данных.
Читайте с любого места.
Удачи!
Slav, кластеры тут вовсе не при чём. Вы уже ведёте речь про физическую организацию данных, а я — про логическую. Для понятия «файл последовательного доступа» совершенно неважно как именно будет организовано хранилище — будь то на перфокартах, перфолентах, магнитных барабанах, лентах или дисках.
А чем конец хуже начала. Разве тем, что записи туда добавляются, но ведь необязательно, что в момент, когда я хочу последовательно читать с конца, файл будет обновляться, поэтому - почему бы было бы не сделать системные инструменты, позволяющие читать ( в монопольном режиме хотя бы ) текстовые файлы построчно с конца .
Проблема в том, что неизвестно, с какого места начинается n-ная (не первая) строка файла. Где заканчивается n-ная (не последняя) строка. Точно так же ничего неизвестно о том, сколько, например, строк в файле. Таким образом, единственным способом добраться до n-ной строки, является метод последовательного чтения от начала файла к концу файла (чтобы лучше представлять, чем сие обусловлено — посмотрите, например, на функцию ReadFile (Windows)).
Можно, конечно
, где-то (отдельно или в том же файле) хранить смещения, где начинаются очередные строки, и пользоваться этими данными. Про такой механизм уже упомянул выше коллега Slav, говоря о базах данных. Но, естественно, сие уже не будет являться «текстовым файлом последовательного доступа».
Проблема в том, что неизвестно, с какого места начинается n-ная (не первая) строка файла. Где заканчивается n-ная (не последняя) строка. Точно так же ничего неизвестно о том, сколько, например, строк в файле. Таким образом, единственным способом добраться до n-ной строки, является метод последовательного чтения от начала файла к концу файла
imho, Скорее все же кластеры тут как-то больше "при чем", а еще больше "при чем" тут механизм считывания устройств хранения информации, т.к. он хоть для HDD и называется "с произвольным доступом" , но считывание - то происходит от меньших адресов кластеров к большим (диск не умеет крутиться в обратную сторону). Именно поэтому, чтобы получить данные с более старшими адресами нужно вначале прочитать данные с более младшими (разобрать их по строкам), а не наоборот. А если бы этого не было, т.е. можно было бы делать наоборот (точнее говоря оно возможно, но затраты получаются в результате заметно больше) , то , как раз был бы способ добраться до n-ной строки методом последовательного чтения от конца к началу файла . Видимо, причина, что нет (а впрочем нет ли?..) системных средств, предлагающих последовательный построчный доступ конца к началу именно в этом.
Коллега, тут Вы путаете семантически разные вещи. Повторю — физическая организация хранилища не имеет никакого отношения к логическому методу доступа к файлу.
Существуют два метода доступа к файлам: последовательный и произвольный (иногда неверно именуемый прямым методом доступа). Оба этих метода используют операции чтение из файла/запись в файл, которые выполняются единственным способом: указанием смещения от начала файла (откуда начинать читать/писать) и количества байт, которое должно быть прочтено/записано.
Так вот, при хранении в файле структурированных данных (проще говоря — набор из элементов одинакового размера) становится возможным произвольный доступ к n-ному элементу, поскольку в данном случае возможно рассчитать смещение от начала файла этого n-ного элемента как «(n-1)*размер элемента (структуры)+1», а количество необходимых для прочтения/записи байт — есть сам размер элемента/структуры. [И читайте его хоть с начала, хоть с конца — причём тут HDD, кластеры и старшие/младшие адреса?!]
Текстовый же файл не является структурированным — его строки, как элементы набора данных, могут иметь разную длину. Посему нет никакой возможности вычислить ни смещение n-ной строки от начала файла, ни её длину — до тех самых пор, пока не будет прочтено всё начало файла до этой строки и самая она.
Update: Приношу свои извинения за некорректно подобранные ссылки; правильные [отчасти
] ссылки таковы:
Последовательные файлы
Файлы с произвольным доступом
Slav, кластеры тут вовсе не при чём. Вы уже ведёте речь про физическую организацию данных, а я — про логическую. Для понятия «файл последовательного доступа» совершенно неважно как именно будет организовано хранилище — будь то на перфокартах, перфолентах, магнитных барабанах, лентах или дисках.
alexii,
Вы неверно меня поняли.
Я как раз имею ввиду логическую организацию файловой системы.
То что мы имеем сейчас - цепочка кластеров, в каждом из которых ссылка только на последующий.
В каталоге же - для каждого файла указан только первый.
Чудес не бывает - дойти до конца можно только по всей цепочке.
Если же в каждом кластере указывать не только последующий, но и предыдущий, а в каталог писать первый и последний кластер файла - то чтение "с конца" не требует никаких специальных усилий.
Кстати, а Вы застали перфокарты?
Я застал.
Для этих носителей, как раз, чтение "с конца" не было проблемой.
Переставляете карты в колоде - и вперед. ![]()
Вы неверно меня поняли.
Возможно. Просто мы говорим о разных вещах. То, о чём говорите Вы — лежит на более низком уровне, не имеющем отношения к понятию метода последовательного доступа к содержимому файла.
Кстати, а Вы застали перфокарты? Я застал.
Угу
, аналогично, коллега.
Для этих носителей, как раз, чтение "с конца" не было проблемой.
Только сие опять-таки имело отношение к физическому чтению данных с носителя. Вы же не хотите сказать, что это позволяло сразу «прочитать» заданную n-ную строку из такого «файла»?
2 alexii >
То, о чём говорите Вы — лежит на более низком уровне, не имеющем отношения к понятию метода последовательного доступа к содержимому файла.
Насколько я понимаю, методы доступа последовательный \ произвольный как раз и появились багодаря технической организации устройств хранения.
Только сие опять-таки имело отношение к физическому чтению данных с носителя. Вы же не хотите сказать, что это позволяло сразу «прочитать» заданную n-ную строку из такого «файла»?
Как и в случае чтения с начала также невозможно сразу без разбора считанного блока данных получить строку.
Вообще , где в последовательном методе доступа закреплено, что он должен выполняться с начала и не имеет права выполняться с конца ?
PS imho
В большинстве случаев, хоть и не обязателно, кластеры файла располагаются по ходу движения дорожки, поэтому логично считывать с начала и разбирать считанные блоки на строки, что и делают системные средства. Но даже , если б файловая система позволяла адресовать от первого последний кластер и существал обратный связный список от последнего к первому, то было бы в общем случае менее производительно считывать от последнего к первому по указанной выше причине.
PSPS видимо системных средств для обратного считывания не существует чисто по историческим причинам, т.к. ничто не мешает сделать их, пусть бы они были и менее произвоительными.
Насколько я понимаю, методы доступа последовательный \ произвольный как раз и появились багодаря технической организации устройств хранения.
Думаю, что теоретические разработки развивались параллельно реальным возможностям по их воплощению, хотя и несколько опережая последних.
…кластеры файла располагаются по ходу движения дорожки, поэтому логично считывать с начала и разбирать считанные блоки на строки, что и делают системные средства.
Опять двадцать пять. Какие кластеры, какие дорожки? Почему, Вы думаете, в большинстве языков программирования в операциях ввода/вывода работа идёт с логическими файлами, а детали конкретной реализации вынесены в отдельные библиотеки?
Бессмысленный разговор получается. Я Вам про Фому, Вы мне про Ерёму.
Почему, Вы думаете, в большинстве языков программирования в операциях ввода/вывода работа идёт с логическими файлами, а детали конкретной реализации вынесены в отдельные библиотеки?
А Вы как думаете ?
...
Вы же не хотите сказать, что это позволяло сразу «прочитать» заданную n-ную строку из такого «файла»?
alexii,
у меня ощущение, что мы обсуждаем разные вопросы.
Я пытаюсь объяснить (в том числе и самому себе - это бывает очень полезно) вот это:
А чем конец хуже начала. Разве тем, что записи туда добавляются, но ведь необязательно, что в момент, когда я хочу последовательно читать с конца, файл будет обновляться, поэтому - почему бы было бы не сделать системные инструменты, позволяющие читать ( в монопольном режиме хотя бы ) текстовые файлы построчно с конца .
При чем тут произвольный доступ? При чем тут чтение n-ой строки?
Я обсуждаю чтение в разных направлениях (с начала, с конца, вперед, назад) - а Вы чтение с произвольного места.
Еще раз повторюсь - чтение в любом направлении не поддерживается именно файловой системой. Потому и в языках программирования есть Read, но нет что-то типа ReadForward - ReadBackward. По той простой причине, что реализовать ReadBackward физически невозможно.
В подтверждение своих слов могу привести пример файловой системы, которая эту возможность поддерживает. Запишите на лазерный диск файл любого фильма, вставьте в плеер и посмотрите минут 5-10. А затем нажмите кнопку "<". И посмотрите то же самое в обратном направлении. Оказывается ничего невероятного в этом нет.
Просто файл записан так, что логические блоки четко соответствуют расположению физических секторов. И для чтения в прямом направлении надо считывать последовательно n, n+1, n+2... сектора, а для чтения в обратном - n, n-1, n-2... Файловая система жесткая и не очень удобная - но зато именно чтение в любом направлении поддерживает.
И для этого никаких специальных "системных средств" не нужно.
... чтение в любом направлении не поддерживается именно файловой системой. Потому и в языках программирования есть Read, но нет что-то типа ReadForward - ReadBackward. По той простой причине, что реализовать ReadBackward физически невозможно...
Столь категоричное утверждение если и справедливо, то лишь для части случаев.
Не знаю, как сейчас, а в старом добром "Си" была функция fseek(). Она позволяла читать файл (текстовый) побайтово в любом направлении. Читать файл можно было и с начала, и с конца, и с произвольного места, причём в любой момент можно было изменить направление чтения. Всё прекрасно работало на MS DOS-овской FAT16.
Таким образом, можно было читать данные от конца файла к его началу. Однако при желании получать в итоге строки возникала задача идентификации начала и конца каждой строки, причём именно потому, что строка - объект переменной длины (о чём уже и упоминал alexii).
Соглашусь с kefi, что так и не понятно, почему нельзя читать построчно с конца. Да, конец нужно сперва найти, ну и что? Когда он найден, что мешает найти начало последней строки и считать её? И n-ую строку с конца тоже можно найти. Что тут невозможного? При чём здесь файловая система и прочее?
Насколько я понял, автору темы нужен метод вроде ReadLine, но который возвращал бы строки, начиная с последней, а не с первой. Вот и всё. Что здесь невозможного?
Dmitrii, подтверждаю. На Python и AutoIt есть встроенные средства помещения курсора в указанное в байтах место файла. И происходит это быстро. К примеру, я проверил на файле размером 8 Гб, поместив курсор на 10 байтов перед концом и эти самые 10 байтов считал. Конечно, таких тонкостей/основ, о которых ведут речь alexii и Slav я не знаю, но мне интересно что мешает читать с конца по байту и как только встречается символ перевода каретки считать это за строку и так дальше, пока не достигнется конец (который уже начало) файла.
Я думаю основной причиной отсутствия API для чтения файлов с конца является то, что это нафиг никому не нужно
. Во-первых это медленнее из-за того, что нужно постоянно перемещать указатель по файлу(читать в обратную сторону бесполезно, ведь всё равно порции по 512 байт надо расшифровывать, а каждые 16 кластеров распаковывать(верно для NTFS)), а во-вторых есть такой объект ядра как "проекция файла"(FileMapping), который позволяет работать с файлом так, будто он находится в памяти, а не на внешнем носителе.
2 Александр_ > В общем-то согласен, кроме фразы " нафиг никому не нужно " - это нужно прикладным программистам не меньше, чем чтение с начала, а системными средствами это можно было бы сделать куда оптимальнее.Просто, видимо, не "нафиг не нужно", а руки не доходят у системщиков и исторически ситуация не меняется.
PS. Надеюсь, - еще не забыли, что речь идет о построчном чтении с конца файла(текстового разумеется).
это нужно прикладным программистам не меньше, чем чтение с начала
Я сам занимаюсь в основном прикладным программированием(не путать с разработкой скриптов) и ни разу мне не приходилось читать файл задом на перёд, да ещё и построчно
. Кстати, замечу, что в winapi вообще нет средств для работы с текстовыми файлами(всё, что есть)- это всё надстройки, а вы аж на системщиков пиняете:).
...
Не знаю, как сейчас, а в старом добром "Си" была функция fseek(). Она позволяла читать файл (текстовый) побайтово в любом направлении. Читать файл можно было и с начала, и с конца, и с произвольного места, причём в любой момент можно было изменить направление чтения. Всё прекрасно работало на MS DOS-овской FAT16.
...
Dmitrii,
если мне не изменяет память, то fseek() ничего не читала, а только перемещала указатель (виртуальный) в файле на любое место. А читать приходилось все равно только вперед.
А виртуально сместиться по файлу - что вперед, что назад - нет никаких проблем. Производя отсчет от первого кластера.
...
и ни разу мне не приходилось читать файл задом на перёд, да ещё и построчно
...
Александр_,
мне тоже за много лет это не приходило в голову.
Но тут решил написать оповещатель об ошибках на сервере: надо читать строку из лог-файла, анализировать, сообщить на мобильник если что-то не так.
Так вот, лог-файл немерянный, управлять его размером я не могу, а читать ну о-о-о-о-чень хочется именно с конца. Ведь там последние сообщения. Не хочу я делать построчный Read - каждый раз проходя записи недельной, а то и месячной давности. И ReadALL'ом тоже не хочу мусор в память грузить.
Мне нужны именно последние записи - а вот как до них добраться быстро и не напрягая винт пока не знаю.
Но тут решил написать оповещатель об ошибках на сервере: надо читать строку из лог-файла, анализировать, сообщить на мобильник если что-то не так.
Так вот, лог-файл немерянный, управлять его размером я не могу, а читать ну о-о-о-о-чень хочется именно с конца. Ведь там последние сообщения. Не хочу я делать построчный Read - каждый раз проходя записи недельной, а то и месячной давности. И ReadALL'ом тоже не хочу мусор в память грузить.
Мне нужны именно последние записи - а вот как до них добраться быстро и не напрягая винт пока не знаю.
Ну во-первых странный способ ведения лога- обычно это несколько файлов(например 1 день/один файл или один час/один файл- зависит от интенсивности записей). Во-вторых такие приложения вроде должны писаться на сях/делфях, а там есть доступ к winapi и проблем с реализацией быть не должно(если кому надо, то могу написать функцию на сях).
... fseek() ничего не читала...
Я написал: "Она позволяла читать",- (собственно чтение, разумеется, выполняла функция getc()).
... А читать приходилось все равно только вперед...
Похоже, сначала надо договориться о том, что следует понимать под словами "вперёд" и "назад", не забывая, опять же, что речь идёт о логических структурах, именуемых файлами (а в данном случае ещё и текстовыми).
Кстати, про пример с плеером оптических дисков: разве указанный Вами эффект достигается только особенностями размещения данных на диске? Если так, то придётся признать следующее:
- текстовый файл, записанный на компакт-диск, можно прочитать построчно от конца к началу;
- текстовый файл, записанный на НЖМД так, что логические блоки четко соответствуют расположению физических секторов, можно прочитать построчно от конца к началу.
Или я чего-то не понимаю?
...
Не хочу я делать построчный Read - каждый раз проходя записи недельной, а то и месячной давности. И ReadALL'ом тоже не хочу мусор в память грузить.
Если в каждых строках огромного лога есть известный шаблон текста, например, текущая/вчерашняя дата, то предлагаю подумать об использовании консольных команд системы. Идея такова - создать строку запуска команды findstr по поиску в текстовом файле даты указанного в параметрах образца (+ некая гибкость в применении регулярных выражений) - а сохраненный вывод уже обрабатывать скриптом.
Думаю, что такая встроенная команда отработает побыстрей построчного чтения скриптом или записи всего файла в массив.
Не вижу особой сложности реализации чтения файлов с конца. Можно воспользоваться средствами SAPI — SAPI.spFileStream.
Так вот, лог-файл немерянный, управлять его размером я не могу, а читать ну о-о-о-о-чень хочется именно с конца.
VBScript: работа с большими текстовыми файлами
Ещё можно подумать о загрузке файла в специальную БД MS SQL Server, такую загрузку можно автоматизировать, сейчас не вспомню как именно, но в MS SQL Server вроде были такие возможности "малой кровью". Дальше работать с этой БД запросами.
Адо будет перебирать записи с начала файла, поэтому не думаю, что этот вариант полезный.
Адо будет перебирать записи с начала файла, поэтому не думаю, что этот вариант полезный.
ADO позволит сделать SELECT, который будет быстро работать. А как уж оно само там "в душе" будет читать, это его трудности
.
Коллеги,
если нужна конкретика - то я имею ввиду как раз лог MS SQL сервера.
Кто в курсе - файл ERRORLOG.
Новая версия файла образуется при перезагрузке сервера - вот такой вот "странный способ ведения лога".
А так как перезагрузка только в крайнем случае - то копится он несколько месяцев.
Поэтому и грузить текстовый лог MS SQL в сам MS SQL как-то... диковато.
Алгоритм становится вообще очень странным: искать новые строчки в логе (в конце файла, кстати), загружать их в базу SQL, а потом обращаться с запросом.
Т.е. этап "чтение последних строчек" таким образом не исключается.
Спасибо за предложенные варианты.
Буду дальше пробовать.
На самом деле "чтение с конца" - реально с конца, а не иммитация разными способами - не такая уж и очевидная вещь.
Похоже, сначала надо договориться о том, что следует понимать под словами "вперёд" и "назад", не забывая, опять же, что речь идёт о логических структурах, именуемых файлами (а в данном случае ещё и текстовыми).
Dmitrii,
ну давайте "договоримся". ![]()
1. Приведенная Вами функция getc() продвигает указатель к началу файла или к концу?
2. Известна ли Вам хотя бы одна функция чтения, которая продвигает указатель к началу файла, что-то типа getc(-1)?
Подчеркиваю, не перемещает виртуальный указатель - это не чтение - а именно читает, и именно к началу?
Кстати, про пример с плеером оптических дисков: разве указанный Вами эффект достигается только особенностями размещения данных на диске? Если так, то придётся признать следующее:
- текстовый файл, записанный на компакт-диск, можно прочитать построчно от конца к началу;
- текстовый файл, записанный на НЖМД так, что логические блоки четко соответствуют расположению физических секторов, можно прочитать построчно от конца к началу.
1. Я не вижу большой разницы между тектовым файлом и любым другим - разве что CR - LF встречается чаще и этому сочетанию придан особый логический смысл.
2. Любой файл "на оптическом диске" (файловая система UDF) без значительных вычислительных затрат может быть прочитан в любом направлении. Просто "читалки" на плеерах пока никто не додумался делать. ![]()
И реализуется эта возможность "вперед-назад" на уровне элементарной микросхемы - правда, при жесткой организации самой файловой системы.
3. Любая файловая система с жесткой организацией позволяет относительно просто реализовать алгоритм "обратного чтения". Я уже приводил пример с перфокартами.
Если Вы на абсолютно чистый винт запишете файл - то формально он будет соответствовать условию "обратного чтения". Но! Файловая система все равно будет знать из каталога только первый кластер, а в каждом будет только ссылка на последующий.
Так что "в конец" придется все равно идти по всей цепочке.
Алгоритм становится вообще очень странным: искать новые строчки в логе (в конце файла, кстати), загружать их в базу SQL, а потом обращаться с запросом.
Я имел в виду загружать весь лог в таблицу БД каким-нибудь Job'ом, исполняющимся периодически. Структурированные текстовые файлы вроде можно так загружать какими-то простыми командами. Может, это и бред — рассуждаю почти наугад.
Я имел в виду загружать весь лог в таблицу БД каким-нибудь Job'ом, исполняющимся периодически. Структурированные текстовые файлы вроде можно так загружать какими-то простыми командами. Может, это и бред — рассуждаю почти наугад.
The gray Cardinal,
в принципе этот вопрос я могу решить и в сях, дельфях, скулях... - открыть текстовый файл, seek-нуть на запомненную в предыдущем запуске позицию, и начать читать сразу только новые сообщения.
Запущу любую из Студий - и вперед.
seek, конечно, не чтение "с конца" - но все-таки на порядок лучше чтения мусора с самого начала.
Но на этом форуме меня всегда поражали изящные и лаконичные решения в 2-3 десятках строк, написанных в обычном Блокноте.
Жаль, что кроме ReadLine и ReadAll ничего другого мы не нашли.
Или плохо искали? ![]()
2. Любой файл "на оптическом диске" (файловая система UDF) без значительных вычислительных затрат может быть прочитан в любом направлении. Просто "читалки" на плеерах пока никто не додумался делать.
И реализуется эта возможность "вперед-назад" на уровне элементарной микросхемы - правда, при жесткой организации самой файловой системы.
Ага, надо только заставить сидюк диск в обратную сторону крутить ![]()
3. Любая файловая система с жесткой организацией позволяет относительно просто реализовать алгоритм "обратного чтения". Я уже приводил пример с перфокартами.
Если Вы на абсолютно чистый винт запишете файл - то формально он будет соответствовать условию "обратного чтения". Но! Файловая система все равно будет знать из каталога только первый кластер, а в каждом будет только ссылка на последующий.
Так что "в конец" придется все равно идти по всей цепочке.
Нет, это не совсем так. Привожу пример организации на NTFS, про MFT и т.п. не рассказываю, поскольку сейчас это не важно. Запись файла выглядит примерно вот так:
|стнадарт.инфо.|имя|данные|Каждый из этих атрибутов состоит из заголовка и значения. Но размер записи фиксирован(если не ошибаюсь, то 1кб). Если данные не уместились то этот атрибут называется нерезидентным, в таких случаях под хранение данных выделяется дополнительное пространство вне MFT(буржуи называют его "run" или "extent", у нас обычно просто "группа"). И вот тут на помощь приходит LCN- это нумерованная от 0 до N последовательность кластеров на всём томе, и VCN- аналогичная нумерованная последовательность, но только для каждого файла своя(т.е. нумеруются только кластеры принадлежащие файлу). Т.о. данные выглядят так:
|Начальный VCN|Соответствующий ему LCN|число кластеров|
Таким образом файловая система знает не только первый кластер:). Например если файл занимает 16 кластеров и нужно попасть на 14-ый(отсчёт с нуля):
|00|1297|8|
|08|4932|4|
|12|6321|4|Из этой таблицы извлекается третья запись и считается отступ(14-12=2), т.о. нужный нам кластер находится под номером 6323.
... seek, конечно, не чтение "с конца" - но все-таки на порядок лучше чтения мусора с самого начала...
Насколько верно я сужу по документации - у объектов WSH нет методов работы с нетекстовыми файлами - всевозможные Open/CreateTextFile, OpenAsTextStream и единственный объект - опять же TextStream. Но последний имеет два метода SkipLine и Skip. Последний - аналог seek.
Skips a specified number of characters when reading a TextStream file.
object.Skip(characters)
Arguments
object
Required. Always the name of a TextStream object.
characters
Required. Number of characters to skip when reading a file.
Если в постановке задачи нет ограничений на использование внешних утилит, то я бы порекомендовал использовать юниксовые порты команд (например, http://unxutils.sourceforge.net/):
tail -n - чтение последних n строк из файла
tac - команда, выводящая в STDOUT строки указанных файлов в обратном порядке
Slav, с терминами "вперёд" и "назад" всё понятно. В такой их интерпретации - читаем "вперёд".
Понятно также и то, что о разнице между текстовым и не текстовым файлами имеет смысл говорить только в контексте восприятия данных человеком, а не вычислительным комплексом.
В данном случае вынужден повторить Ваши слова: "Мы обсуждаем разные вопросы".
Ага, надо только заставить сидюк диск в обратную сторону крутить
Александр_,
я почему-то так и думал - что кто-то предложит еще и крутить диск в обратную сторону. ![]()
Надеюсь, что Вы действительно пошутили.
Предыдущий сектор будет считан на следующем обороте диска.
Главное - мы знаем его номер.
Спасибо за экскурс в NTFS.
Действительно, интересно.
Насколько я знаю, там еще сложнее - те же индексы.
Но вот для "обратного чтения" все это как-то не очень.
Исключительно по моему скромному мнению. ![]()
Спасибо, уважаемые коллеги.
На мой взгляд интересно обсудили.
Особенная благодарность Rumata.
Про Skip я не знал.
На данный момент лично для меня - то что надо.
я почему-то так и думал - что кто-то предложит еще и крутить диск в обратную сторону.
Надеюсь, что Вы действительно пошутили.
Предыдущий сектор будет считан на следующем обороте диска.
Главное - мы знаем его номер.
Тогда это очевидно сводит задачу к SetFilePointer/ReadFile. Причём посекторное чтение таким способом в разы снизит производительность(в секунду диск делает меньше 20-ти оборотов, если попробовать ускорить, то мы можем просто уничтожить диск:)).
А если так попробовать?
Set FSO = CreateObject("Scripting.FileSystemObject")
Set File = FSO.GetFile("test.txt")
Set TextStream = File.OpenAsTextStream(1)
Str = vbNullString
While Not TextStream.AtEndOfStream
Str = TextStream.ReadLine()
Wend
TextStream.Close
MsgBox StrСтраницы 1
Чтобы отправить ответ, вы должны войти или зарегистрироваться