Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Операционные системы > Софт
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 01.05.2015, 15:10   #11
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,792
По умолчанию Работа с файловой системой

Часто использую самые примитивные функции для работы с файлами.
Чтоб с ними работать нужно создавать обьект filesystem
Код:
(f := filesystem)
Самая частая функция, функция поиска файла. Обычно хватает одного вызова для прохода по каталогам, в котором описана анонимка, обрабатывающая случай нахождения файла. Делается это примерно так:

Код:
(call f.find 
    path='d:\1\'
    mask='*.txt'
    recursive
    onfound=(
     (writeln f[attributes] ' ' f[time] ' ' f[date] ' ' f[file] ' ' f[path] ' ' f[size])
    )
)
Если recursive не значится в команде значит прохода по подкаталогам не будет. Как всегда в анонимке итератор получает свойство массива с данными найденного файла

Так же есть функции копирования
Код:
(call f.copy from='Файлик откуда' to='файлик куда')
И переименования
Код:
(call f.rename from='Файлик откуда' to='файлик куда')
У них одна и та же основа.

Функция удаления
Код:
(call f.delete file='*.txt')
Хоть и с маской но не умеет проходить по подкаталогам. А надо бы допилить и до такого.

Функция создания каталога
Код:
(call f.createfolder 'd:\1' 'd:\2' 'd:\3\rt\')
Создает каталоги, перечисленные в параметрах.

Функция проверки наличия каталога
Код:
(call f.exist dir='d:\1')
Или файла:
Код:
(call f.exist file='d:\1')
Использую в основном так:
Код:
(pth := 'z:\backupbase\')
(f := filesystem)
(dt := (asdate 01.01.1900))
(call f.find 
    path=pth 
    mask='*.dat'
    onfound=(
     (d := (extract date from=f[date]))
     (if (dt < d) ((dt := d) (lastfile := f[file])))
    )
)
(write 'Последний за ' dt ' файл: ' lastfile)
(write 'Копирую: ' (call f.copy from=(pth + lastfile) to=('d:\Бэкапы\Товарка\' + lastfile)))
Т.е. проход по backupbase, получение списка файлов, и запоминание того, у кого дата создания больше. После чего он копируется в другое место. Это у меня каждое утро вызывается, чтоб собрать бэкапы ночные с серверов.
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 01.05.2015, 15:14   #12
Vapaamies
Ваш К. О.
Участник клуба
 
Аватар для Vapaamies
 
Регистрация: 26.12.2012
Сообщений: 1,755
По умолчанию

Что-то многим в Рунете лисповские скобки нравятся, даже не ожидал.

А прямого импорта системных функций нет? Чтобы можно было написать что-то типа:
Код:
(func CloseHandle(a) := (stdcall 'kernel32.dll'('CloseHandle')))
Так язык выглядит игрушечным.
Vapaamies вне форума Ответить с цитированием
Старый 01.05.2015, 15:26   #13
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,792
По умолчанию FTP Клиент

Очень часто используемые действия - работа с FTP.
Для этого есть класс, подключаемый примерно так:
Код:
(f := ftp host='100.22.1.17' user='ftp' pass='ftp' port=21)
Параметры опциональны, и могут быть описаны позже при вызове методов.
Думаю не обязательно пояснять что они означают, названия говорят сами за себя.

Для загонки файлов в стойло FTP есть следующий метод:
Код:
(call f.put to='/home/ftpdir/SolidWorkStamp.pas' from='d:\1\SolidWorkStamp.pas')
Ну или по маске:
Код:
(call f.put to='/home/ftpdir/' from='d:\1\*.pas')
from - указывает что загонять
to - куда (либо конкретно файл, либо каталог, если загон нескольких файлов)

Получение файлов аналогично:
Код:
(call f.get from='/home/ftpdir/Drop_DB_Archive_Part.sql' to='d:\1\Drop_DB_Archive_Part.sql')
Но здесь увы не предусмотренно получение по маске. Пока что.

Посыл команды серверу:
Код:
... := (call f.cmd text='NLIST')
Результат команды соответственно возвращается в виде строки.
Собственно коды ответа в результате не режутся. Если нужно их отрезать то делается это отдельно. Можно будет допилить чтоб отрезались, но пока меня устраивает.

Получение списка с FTP:
Ну тут два варианта:
Код:
(call f.list path='c:\windows\system32')
(for i in f 
 (writeln i)
)
Т.е. список запоминается как массив в объекте f
И потом обычный проход итератором.
Либо же анонимкой:
Код:
(call f.list 
 path='/windows/system32' 
 onfound=(func 
   (write f[file] ' - это имя файла')
 )
)
Второе предпочтительнее, и преимущественно используется.
Можно было бы конечно имя не пихать в массив с индексом file, но я делал на будущее, когда понадобится получать не просто краткий список а еще дату, время и атрибуты.

Больше я не доделывал фичек для работы с FTP, пока хватает и такого. А там видно будет.
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 01.05.2015, 15:28   #14
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,792
По умолчанию

Цитата:
Что-то многим в Рунете лисповские скобки нравятся, даже не ожидал.
Ну дык мне вот они понравились за простоту реализации синтанализа.
Да и утверждение "муляют глаза куча скобок" скорее миф. Писать просто не надо так чтоб муляло.
Цитата:
А прямого импорта системных функций нет? Чтобы можно было написать что-то типа:
В разработке. Помнишь мою тему про OLE? Вот закончу (устаканю ее) и возьмусь за импорт библиотек. Просто руки не дошли, но в TO DO этот пункт есть.
Цитата:
Так язык выглядит игрушечным.
А я и не претендую на суперконкуренцию )
Тем паче что простота языка оказывается важной. Вон сколько у PHP всякого наворочали. А толку? Используется от силы 5-10%
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 01.05.2015, 15:54   #15
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,792
По умолчанию HTTP

По аналогии с FTP есть возможность работы с HTTP.
Причем реализован как клиент так и сервер, хотя второе на стадии прототипа, но уже работает. Правда требует марафета.

Класс http:
Код:
(h := http port=1234)
Порт опционален. По умолчанию 80-й, но случаи бывают разные

Получение контента в файл:
Код:
(call h.get 
 url="http://upload.wikimedia.org/wikipedia/commons/4/42/Jrobinson.jpg" 
 to='d:\1\Jrobinson.jpg'
 proxy='100.25.11.18:8080'
)
Прокси опционален. Порт в нем можно не указывать, тогда по дефолту будет назначен 80-й.
Параметр to тоже опционален, если он указан - результат идет в файл, иначе возвращается функцией в переменную.
Если идет возврат в переменную, то по умолчанию происходит парсинг DOM. Для этого использую MSHTML.

Соответственно после получения можно и пройтись по "дому"
Для этого существует метод scan
Код:
(call h.scan
  (if (h[tag] = 'A') (writeln h[html]) )
)
Это пример получения элементов <a> дома.
Сразу оговорюсь - иерархия дома разрушается, все теги считаются тегами верхнего уровня. Это было сделано специально. В будущем планирую пересмотреть составление списка тегов иерархически или по крайней мере XPath прикрутить.
Да собсно для качалки сайтов и парсинга этого пока хватает.

Так. Теперь сервер:
Сходу маленький пример:
Код:
(h := http indyserver port=9980 onget=(
    (if (h[document] = '/') 
        (pth := ((tooly appdir) + 'AppDir\html\Tooly.html')) 
        (pth := ((tooly appdir) + 'AppDir\' + (extract ext from=h[document]) + h[document]))
    )
    (pth := (replace in=pth from='/' to='\'))
    (writeln pth)
    (result from=pth)
))
(for () (1 = 1) () (sleep))
Флаг indyserver указывает на то что компонент будет не клиентом а сервером. Он прослушивает указанный порт, и при поступлении запроса генерит событие onget, которое и обрабатывает запрос.
В примере массив переменки-сервера получает параметр document, который хранит имя и (или) путь к документу, и сами параметры, тоже передаваемые в качестве элементов массива.
Т.е. запрос типа http://Localhost/MyDoc?para=1&para2=ololo
будет доступен по элементам h[para] h[para2] и h[document] будет равняться "/MyDoc"
Возврашает нагенеренную страницу оператор
Код:
(result from=pth)
Если указан параметр from - контент считывается из файла, иначе просто возвращается строка.
Что-то типа
Код:
(result '<html><body>Тут ХаТэМэЛэ</body></html>')
По факту вернуть значение от сервера может любой последний оператор.
Например я могу в конце обработчика просто написать
Код:
('<html><body>' + КакаяНибудьПеременка + '</body></html>')
И эта операция будет считаться возвратом результата поскольку она последняя.
Вообще я предусмотрел у себя правило, согласно которого последняя операция является возвратом результата. Как оказалось это очень удобно.
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 01.05.2015, 16:07   #16
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,792
По умолчанию SMTP. Отправка почты

Для этого есть класс mail
Код:
(ml := mail)
Вся отправка заключена в вызове всего одного метода:
Код:
(if 
         (call ml.send 
				 host='192.168.0.3' 
                                 port=25
                                 pass='Парольчик'
				 Sender='<admin@domain.local>' 
				 Recipient='<q@me.com>'
				 Subject='Тема'
				 Text='Русский'
	)
 (write 'Улетело')
 (write 'Ошибка: ' (call ml.error))
)
Порт, пароль, тема и текст опциональны

Метод send отправляет через MAIL сервер, указываемый параметром host определенному кренделю письмецо. Да больше и нечего сказать.

Если необходимо что-то вложить можно сделать это следующей конструкцией:
Код:
(call ml.addfile file='d:\Какой-то файлик.docx')
Перед отправкой
Константы естественно могут быть заменены на выражения:
Код:
(call ml.addfile file=('d:\' + Переменка))
Чаще всего использую в сочетании с find из filesystem, когда нужно послать некоторые файлы.

Минусы в кодировке, иногда письмо (текст или тема) приходят кракозябликами. Причем разные сервера по разному воспринимают. И почему то не работает указание через запятую нескольких получателей.
Но это я буду разбираться позже.
I'm learning to live...

Последний раз редактировалось Stilet; 01.05.2015 в 20:38.
Stilet вне форума Ответить с цитированием
Старый 01.05.2015, 22:26   #17
Vapaamies
Ваш К. О.
Участник клуба
 
Аватар для Vapaamies
 
Регистрация: 26.12.2012
Сообщений: 1,755
По умолчанию

Цитата:
Сообщение от Stilet Посмотреть сообщение
Ну дык мне вот они понравились за простоту реализации синтанализа.
На самом деле, если заглянуть в мой план, то у меня синтаксические возможности тоже будут раскручиваться в несколько этапов. И первый синтаксис, который будет реализован, носит рабочее название "Лисп-скобка-скобка" по аналогии с "Си-плюс-плюс".

Вместе с ним будет также реализован импорт системных функций: stdcall, cdecl, register и прочих. Ориентированность на системное программирование дает о себе знать.

Всё это вместе должно дать возможность писать осмысленные программы на Канторе, думаю написать что-нибудь вроде тетриса.

А сейчас, выходит, я застрял на реализации ключевого компонента системы -- БД кода.
Vapaamies вне форума Ответить с цитированием
Старый 02.05.2015, 09:15   #18
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,792
По умолчанию

Цитата:
Лисп-скобка-скобка
Хе L(( или L)) это уже смайл какой-то киберпанковый.
Тогда уж ((K)) - символ языка Кантор.
Цитата:
Вместе с ним будет также реализован импорт системных функций: stdcall, cdecl, register и прочих
Я пока этим не буду заморачиваться. Успею еще.
Цитата:
я застрял на реализации ключевого компонента системы -- БД кода.
А что за проблемы могут быть с реализацией работы с БД? Че там сложного?
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 02.05.2015, 09:55   #19
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,792
По умолчанию FireBird. Особое внимание огнептицы (или с чего начиналась Алиса)

Нда. На эту "ангри бирд" все в основном изначально и затачивалось. Обьем работ с этой СУБД у меня коллосальный, поэтому класс работы с огнептичкой был первым.
Так то там все тоже самое что и выше описано в ADO, за исключением некоторых отличий.

Создание объекта:
Код:
(fb := firebird 
  host='127.0.0.1' 
  path='d:\Base.gdb'
  user='Логин'
  pass='пароль'
)
Дополнительные параметры не указываются, но планирую в будущем (возможно) и такую штуку прицепить, хотя не сталкивался на практике с какими-то особыми настройками БД как локаль.

Кратко приведу основные методы, схожие с ADOшным классом:

open - То же самое что и в ADO, открывает набор. В параметр sql передается запрос

exec - Выполняет команду без открытия. параметр sql имеет то же назначение

next - Переход на следующую запись.

error - Текст ошибки или пустая строка
commit - Коммит (роллбэка тоже пока не прицепил)
noteof - Такая же "афигевация" типа not eof для набора.
scan - Проход по набору. Тоже заменил цикл, сделав проход удобным

fieldcount - Кол-во полей
fieldname - Имя поля. В качестве параметра без имени передается номер
fieldtype - Тип поля (в виде строки).
fieldsize - Размер поля (тоже по номеру поля)
isnull - Проверка на NULL.

Далее есть несколько плюшек, которые мне по работе необходимы. О них подробнее:

Код:
(call fb.gback base='d:\База.GDB');
Устаревшая версия бэкапинга. Основанная на команде
Код:
c:\Program Files\Firebird\Firebird_1_5\bin\gbak.exe" -b -v -ig -g -l -user SYSDBA -password masterkey "[base].gdb" "[base].gbk"
Уже не использую, но на память оставил.

Код:
(call fb.backup from='d:\База.GDB' to='d:\База.GDK')
А вот это уже поновее. Используется компонент TFBAdmin. Который идет стандартно в поставке последнего Лазаруса. Да в Делфи тоже он есть, если мне память не изменяет. При этом бэкапить можно удаленно по хосту, который при создании объекта указывается.

Код:
(call fb.restore to='d:\База.GDB' from='d:\База.GDK')
Восстановление. Тот же компонент.

Код:
(call fb.export table='Имя таблицы' where='Условие выгрузки' to='d:\query.sql')
Эта функция путем запроса select * from Имя таблицы Условие выгрузки формирует текстовый скриптовой файл, который представляет из себя команды INSERT с данными, хранящимися в таблице. Те кто знаком с IBExpert в курсе что у него есть такая мегаполезная опция.
Параметр where опционален, и может указать условие отбора для выгружаемого. Параметр to указывает на имя файла, куда будет сформирован скрипт.

И так оно и есть. Очень часто использую выгрузку для того чтоб перенести данные на другую базу.
По скорости гораздо быстрее получается чем прямая заливка из БД в БД.
Смысл в том что данные выгруженные в скрипт сжимаются в zip, передаются приемнику, разжимаются и заливаются, считываясь из файла.
В результате я получаю файлик примерно такого содержания:
Код:
-- Exported 4 records
--DELETE FROM Cyties;
INSERT INTO Cyties (id, name, code) VALUES 
    (3, 'м. Слов`янськ', '419');
INSERT INTO Cyties (id, name, code) VALUES 
    (4, 'м. Костянтинівка', '410');
INSERT INTO Cyties (id, name, code) VALUES 
    (23, 'м. Дружківка', '408');
INSERT INTO Cyties (id, name, code) VALUES 
    (26, 'м. Краматорськ', '407');
commit work;
Применение в коде такое же как и вышеописанного ADO. Зависимости от версии FB нет (по крайней мере и на 1,5 и на 2,5 работает одинаково).
I'm learning to live...

Последний раз редактировалось Stilet; 02.05.2015 в 09:57.
Stilet вне форума Ответить с цитированием
Старый 02.05.2015, 10:28   #20
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,792
По умолчанию XML.

Вообще я особое внимание XML не уделял, ибо задачи с его участием у меня не часты. Но есть. Поэтому пришлось и таким дополнить.
Код:
(x := xml 
 file='d:\1\sheet1.xml'  
 xpath='Условия'
 native
)
File соответственно определяет из какого файла брать.
параметр-флаг native указывает использование самописного мной парсера XML, который понятное дело очень урезан зато быстр и прост. Основан (или точнее наследует) на синтаксическом анализаторе самой Алисы, но немного дополнен.
Если этот флаг не указываю, подключается виндовский MSXML.
И вот во втором случае есть возможность отбора по XPath.

Более менее живых примеров пожалуй нет, за исключением одного единственного модуля
Код:
(apath := 'D:\archive\')

(fs := filesystem)
(x := xml)

	(call fs.find
		path=apath
		mask='*.xml'
		onfound=(func
		  (dt := fs[date])
		  (y := (extract year from=dt))
          (call x.load file=(apath + fs[file]))
		 
		    (st := (call x.attr 1 State Cd))
			(if (st = 'ST') (
				(writeln 
				 'Date=' 	(call x.attr 1 Purchase Date)
				 ' Date2=' 	(call x.attr 1 DateTime Date)
				 ' Time='	(call x.attr 1 DateTime Time)
				 ' FileDate=' dt
				)
			))

	   )
	)
Делает он следующее: метод Find проводит поиск файлов в некоем каталоге, Найденный файл в событии onfound передается в x.load, которая всасывает его в MSXML и парсит.

Далее вступает функция x.attr, в параметры которой передается список узлов DOM документа либо по имени либо по номеру. Функция возвращает значение аттрибута последнего элемента из списка.
Т.е. (call x.attr 1 State Cd) по факту проходит путь /@first/State и возвращает значение аттрибута Cd.
Можно было XPath применить. Не применил. Почему? Х.з. Просто не применил. Тем паче что с флагом native он бы не работал.

Далее проверяется значение этого аттрибута и считываются из того же корневого узла другие аттрибуты других элементов.

Увы самого XML у меня нет, поэтому пример рукописный:
Код HTML:
<Pay id="002" Code="9G0722">
  <Purchase PostCode="51256" Date="25.01.2011" /> 
  <State Cd="VO" /> 
  <DateTime Date="31.05.2011" Time="13:59:05" />
  <MSGDetails>Фактура</MSGDetails> 
</Pay>
В общем что-то в таком ключе.

Кроме attr есть метод text, который получает текст тега а не его аттрибутику.
Т.е.
Код:
(call x.text 1 MSGDetails)
вернет мне слово "Фактура".

Так же есть метод tag. Который получает имя тега. По номеру естесственно.
Т.е.
Код:
(call x.tag 1 3)
вернет мне имя DateTime.
Если такого тега в пути нет вернет False.

Конечно же и тут не обошлось без метода scan.
Проход по всем элементам с указанием пути. Дом не рушится, как при работе с HTML
При проходе итератор объекта получает массив с элементами path (путь в доме) text (текст в теге)
и tag (имя элемента).

Простой такой примерчик:
Код:
(writeln (x := xml file='d:\1\sheet1.xml' native))
(call x.scan where=(x[path] = '/sheetdata/row/c/v')
 (writeln x[text])
)
Т.е. уже мои непомерные амбиции замахнулись на конфронтацию с стандартным XPath. Прикрутил свой селектор. Вот такой вот в виде указания методу сканирования какие элементы по какому пути отбирать.
Работает кстати не хуже самого XPath, так что остается только понаворотить его до уровня самого XPath. Но это если мне захочется особой конкуренции. Пока хватает и этого, главное сама база фильтрования есть, а допиливать ее дело не хитрое.

Класс этот только читатель. Редактировать в нем документы не предусмотренно. Может быть потом сделаю это если понадобится.
I'm learning to live...
Stilet вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Хочу написать программу для себя Marishka.S Помощь студентам 7 02.10.2011 17:23