Программирование на языке Ruby - [178]

Шрифт
Интервал

• >ActiveDirectory позволяет легко взаимодействовать с экземплярами Active Directory, работающими на серверах под управлением Microsoft Windows;

• >ruby-inifile позволяет работать с ini-файлами (читать, разбирать и обновлять их).

В сети есть еще много библиотек, которые могут вам пригодиться. Ищите их на сайтах http://raa-ruby-lang.org и http://rubyforge.org.

14.8. Работа с файлами, каталогами и деревьями

При выполнении рутинных задач приходится много работать с файлами и каталогами, в том числе с целыми иерархиями каталогов. Немало материала на эту тему вошло в главу 4, но кое-какие важные моменты мы хотим осветить здесь.

Поскольку ввод/вывод — вещь системно-зависимая, то для различных систем приходится применять разные приемы. Если сомневаетесь, экспериментируйте!..

14.8.1. Несколько слов о текстовых фильтрах

Многие инструменты, которыми мы постоянно пользуемся (как поставляемые производителем, так и разрабатываемые собственными силами), — просто текстовые фильтры. Иными словами, они принимают на входе текст, каким-то образом преобразуют его и выводят. Классическими примерами текстовых фильтров в UNIX служат, в частности, программы >sed и >tr.

Иногда файл настолько мал, что целиком помещается в памяти. В этом случае возможны такие виды обработки, которые по-другому было бы сложно реализовать.

>file = File.open(filename)

>lines = file.readlines

># Какие-то операции...

>lines.each { |x| puts x }

Бывает, что нужно обрабатывать файл построчно.

>IO.foreach(filename) do |line|

> # Какие-то операции...

> puts line

>end

Наконец, не забывайте, что все имена файлов, указанные в командной строке, автоматически собираются в объект >ARGF, представляющий конкатенацию всех выходных данных (см. раздел 14.2.2). Мы можем вызывать, к примеру, метод >ARGF.readlines, как если бы >ARGF был объектом класса >IO. Вся выходная информация будет, как обычно, направлена на стандартный вывод.

14.8.2. Копирование дерева каталогов (с символическими ссылками)

Пусть нужно скопировать целое дерево каталогов в новое место. Сделать это можно по-разному, но если в дереве есть символические ссылки, задача усложняется.

В листинге 14.5 приведено рекурсивное решение. Оно достаточно дружелюбно — контролирует входные данные и выводит информацию о порядке запуска.

Листинг 14.5. Копирование дерева каталогов

>require "fileutils"


>def recurse(src, dst)

> Dir.mkdir(dst)

> Dir.foreach(src) do |e|

>  # Пропустить . и ..

>  next if [".",".."].include? e

>  fullname = src + "/" + e

>  newname = fullname.sub(Regexp.new(Regexp.escape(src)),dst)

>  if FileTest:rdirectory?(fullname)

>   recurse(fullname,newname)

>  elsif FileTest::symlink?(fullname)

>   linkname = 'ls -l #{fullname}'.sub(/.* -> /,"").chomp

>   newlink = linkname.dup

>   n = newlink.index($oldname)

>   next if n == nil

>   n2 = n + $oldname.length - 1

>   newlink[n..n2] = $newname

>   newlink.sub!(/\/\//,"/")

>   # newlink = linkname.sub(Regexp.new(Regexp.escape(src)),dst)

>   File.symlink(newlink, newname)

>  elsif FileTest::file?(fullname)

>   FileUtils.copy(fullname, newname)

>  else

>   puts "??? : #{fullname}"

>  end

> end

>end


># "Главная программа"


>if ARGV.size != 2

> puts "Usage: copytree oldname newname"

> exit

>end


>oldname = ARGV[0]

>newname = ARGV[1]


>if ! FileTest::directory?(oldname)

> puts "Ошибка: первый параметр должен быть именем существующего каталога."

> exit

>end


>if FileTest::exist? (newname)

> puts "Ошибка: #{newname} уже существует."

> exit

>end


>oldname = File.expand_path(oldname)

>newname = File.expand_path(newname)


>$оldname=oldname

>$newname=newname


>recurse(oldname, newname)

Возможно, и существуют варианты UNIX, в которых команда >cp -R сохраняет символические ссылки, но нам о них ничего не известно. Программа, показанная в листинге 14.5, была написана для решения этой практической задачи.

14.8.3. Удаление файлов по времени модификации и другим критериям

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

Ниже представлена небольшая программа, удаляющая файлы, которые в последний раз модифицировались раньше указанного момента (заданного в виде объекта >Time):

>def delete_older(dir, time)

> Dir.chdir(dir) do

>  Dir.foreach(".") do |entry|

>   # Каталоги не обрабатываются.

>   next if File.stat(entry).directory?

>   # Используем время модификации.

>   if File.mtime(entry) < time

>    File.unlink(entry)

>   end

>  end

> end

>end


>delete_older("/tmp",Time.local(2001,3,29,18,38,0))

Неплохо, но можно обобщить. Создадим метод >delete_if, который принимает блок, возвращающий значение >true или >false. И будем удалять те и только те файлы, которые удовлетворяют заданному критерию.

>def delete_if(dir)

> Dir.chdir(dir) do

>  Dir.foreach(".") do |entry|

>   # Каталоги не обрабатываются.

>   next if File.stat(entry).directory?

>   if yield entry

>    File.unlink(entry)

>   end

>  end

> end

>end


># Удалить файлы длиннее 3000 байтов.

>delete_if("/tmp") { |f| File.size(f) > 3000 }


># Удалить файлы с расширениями LOG и BAK.

>delete_if("/tmp") { |f| f =~ /(log|bak)$/i }

14.8.4. Вычисление свободного места на диске

Пусть нужно узнать, сколько байтов свободно на некотором устройстве. В следующем примере это делается по-простому, путем запуска системной утилиты:


Рекомендуем почитать
Графика DirectX в Delphi

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


Вторая жизнь старых компьютеров

Сейчас во многих школах, институтах и других учебных заведениях можно встретить компьютеры старого парка, уже отслужившие свое как морально, так и физически. На таких компьютерах можно изучать разве что Dos, что далеко от реалий сегодняшнего дня. К тому же у большинства, как правило, жесткий диск уже в нерабочем состоянии. Но и выбросить жалко, а новых никто не дает. Различные спонсоры, меценаты, бывает, подарят компьютер (один) и радуются, как дети. Спасибо, конечно, большое, но проблемы, как вы понимаете, этот компьютер в общем не решает, даже наоборот, усугубляет, работать на старых уже как-то не хочется, теперь просто есть с чем сравнивать.


DirectX 8. Начинаем работу с DirectX Graphics

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


Симуляция частичной специализации

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


Обработка событий в С++

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


Питон — модули, пакеты, классы, экземпляры

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