Neste artigo vamos explorar a linguagem Ruby e os seus recursos para manipulação de ficheiros e directórios bem como as capacidades de Input/Ouput disponíveis. Para isso vão ser utilizadas as bibliotecas mais comuns como Dir, File e IO. Embora existam outras mais recentes e com mais recursos estão são as mais comuns, de simples utilização e que servem para base de bibliotecas mais recentes.
Directórios
Para trabalhar com directórios vamos utilizar a classe Dir
. Esta classe disponibiliza diversos métodos que permitem aceder e manipular directórios de forma rápida .
Vamos começar por ver um exemplo simples, um pequeno script que verifica se o directório actual é o definido pelo programa. Depois de passar para o referido directório todo o conteúdo é impresso um a um.
WORK_DIR = "/home/magician/" if Dir.pwd != WORK_DIR Dir.chdir( WORK_DIR ) end Dir.foreach( WORK_DIR ) { |nome| puts nome }
É possível ainda criar e eliminar directórios de forma muito simples, bastando usar os métodos mkdir
e rmdir
que a classe Dir
dispõe.
Dir.mkdir( "/home/magician/Ruby", 755 ) Dir.rmdir( "/home/magician/Ruby" )
O exemplo acima não faz mais do que criar um directório no caminho dado e com as permissões dadas. Estas permissões são opcionais, podemos apenas dar o caminho. Em seguida eliminamos o directório criado com o método rmdir
. Podíamos utilizar o método delete em detrimento ao método rmdir
, pois ambos fazem exactamente o mesmo.
A classe Dir
também permite criar streams a directórios, permitindo desta forma percorrer o conteúdo de directórios de forma mais flexível do que usando o método foreach mostrado anteriormente.
dir = Dir.open( "/home/magician/" ) dir.path #=> "/home/magician" dir.tell #=> 0 dir.read #=> "Ficheiro 1" dir.tell #=> 599320 dir.read #=> "Ficheiro 2" dir.rewind dir.close
Como podemos ver na linha 1 é aberta uma ligação ao directório. A partir dai podemos, entre outras coisas, percorrer todos os ficheiros e directórios contidos no directório aberto. O método tell
(linha 5 e 9) retorna a localização do apontador sob forma de inteiro, o método read
(linha 7 e 11) retorna sob forma de string a próxima entrada no directório, retornando nil
quando não existirem mais entradas. Por fim o método rewind
(linha 13) permite colocar o apontador da stream de novo no inicio e método close
(linha 15) fecha a ligação ao directório.
Ficheiros
Criar um ficheiro não podia ser mais simples, basta utilizar a classe File
.
file = File.new( "exemplo.txt", "w" )
O exemplo acima cria o ficheiro exemplo.txt
e abre o ficheiro em modo de escrita. Vamos agora ver que outros modos de abertura e criação de ficheiros existem.
r
: Read-Only. Começa no início do ficheiro.r+
: Read-Write. Começa no início do ficheiro.w
: Write-Only. Passa o tamanho do ficheiro a zero ou cria um novo ficheiro para escrita.w+
: Read-Write. Passa o tamanho do ficheiro a zero ou cria um novo ficheiro para escrita e leitura.a
: Write-Only. Começa no fim do ficheiro caso este exista, caso contrário cria o ficheiro para escrita.a+
: Read-Write. Começa no fim do ficheiro caso este exista, caso contrário cria o ficheiro para escrita e leitura.b
: (DOS/WIN only) Binary.
Depois de criarmos um ficheiro, podemos precisar de apagar o ficheiro ou até mesmo mudar o nome desse ficheiro. Este processo é também muito simples, para isso a classe File
disponibiliza os métodos rename
e delete
que permitem estas operações.
File.new( "exemplo.txt", "w" ) File.rename( "exemplo.txt", "novoExemplo.txt" ) File.delete( "novoExemplo.txt" )
O exemplo acima cria o ficheiro exemplo.txt
(linha 1), em seguida o nome do ficheiro é modificado de exemplo.txt
para novoExemplo.txt
(linha 2), por fim o ficheiro é eliminado (linha 3).
A classe File
permite ainda realizar mais algumas operações úteis, como por exemplo verificar se um ficheiro existe, se é um directório, se é possível ler ou escrever no ficheiro, entre outras. Vamos ver alguns exemplos:
File.exist?( "ficheiro.txt" ) File.file?( "ficheiro.txt" ) File.directory?( "ficheiro.txt" ) File.readable?( "ficheiro.txt" ) File.writable?( "ficheiro.txt" ) File.executable?( "ficheiro.txt" ) File.zero?( "ficheiro.txt" ) File.size( "ficheiro.txt" ) File.size?( "ficheiro.txt" )
O exemplo mostra algumas das mais importantes operações sobre ficheiros. Na linha 1, o método exist?
verifica se o ficheiro existe retornando true
ou false
, em seguida nas linhas 3 e 5 verificam se o ficheiro dado no path é realmente um ficheiro ou se é um directório. Nas linhas 7 e 9 os métodos readable?
e writable?
verificam se é possível ler ou escrever no ficheiro e na linha 11 o método executable?
verifica se o ficheiro é ou não executável. No final do exemplo podemos ver os métodos zero?
, size
e size?
. O método zero?
verifica se o ficheiro tem ou não tamanho igual a zero, os métodos size
e size?
fazem exactamente o mesmo que retornar o tamanho do ficheiro em bytes, com a diferença que caso este seja nulo, o primeiro retorna 0
e o segundo nil
. Para além destes métodos é ainda possível obter mais algumas informações sobre os ficheiros como por exemplo data de criação, de edição e do ultimo acesso. Vamos por isso ver um exemplo desta funcionalidades.
File.ctime( "ficheiro.txt" ) #=> Thu Jan 21 19:55:16 +0000 2008 File.mtime( "ficheiro.txt" ) #=> Thu Jan 21 19:55:16 +0000 2008 File.atime( "ficheiro.txt" ) #=> Thu Jan 25 19:55:16 +0000 2008
Como podemos ver, na linha 1 o método ctime
retorna uma string como a apresentada acima com a data e hora a que o ficheiro foi criado, o mesmo se passando com os métodos mtime
(linha 3) e atime
(linha 5), mas neste caso estes métodos retornam a informação referente à última modificação e ao último acesso do ficheiro respectivamente.
A classe File
tem ainda mais um recurso bastante útil que é o chmod
. Este método permite alterar as permissões de acesso ao ficheiro. As masks para as permissões são as seguintes (r – read, w – write, x – execute):
- 0400 – r para o dono.
- 0200 – w para o dono.
- 0100 – x para o dono.
- 0040 – r para o grupo.
- 0020 – w para o grupo.
- 0010 – x para o grupo.
- 0004 – r para os outros.
- 0002 – w para os outros.
- 0001 – x para os outros.
- 4000 – Altera o user ID na execução.
- 2000 – Altera o group ID na execução.
- 1000 – Salva texto em swap mesmo depois de usar.
A utilização do método chmod
é muito simples, basta abrir o ficheiro como foi mostrado anteriormente e executar o método chmod
.
file = File.new( "ficheiro.txt", "r" ) file.chmod( 0644 )
O exemplo acima dá permissão de de leitura de escrita (4 + 2) ao dono e de leitura ao grupo e todos os outros utilizadores.
Input/Ouput de Ficheiros
Ruby tem ainda mais uma classe muito útil, a classe IO
. Esta pode ser usada isoladamente ou em conjunto com a classe File
, e permite trabalhar com fluxos de input e output. Em seguida vamos ver alguns exemplos da utilização dos recursos desta classe através da classe File
.
src = File.open("exemplo.txt","r") puts src.readline #=> Linha 1 puts src.readline #=> Linha 2 puts src.readline #=> Linha 3 src.flush src.close
O exemplo acima abre o ficheiro em modo de leitura e lê as três primeiras linhas do ficheiro. Podíamos ainda utilizar o método gets que tem exactamente o mesmo funcionamento, com excepção de que o readline
lança uma excepção quando o ficheiro chega ao fim. Para além de ler é também possível escrever para o ficheiro.
dst = File.open("exemplo.txt","w") dst.puts("Linha 1") dst.puts("Linha 2") dst.puts("Linha 3") dst.flush dst.close
Este exemplo utiliza o método puts
para escrever no ficheiro de destino, a cada execução do puts
é automaticamente inserido um \n
, para escrever sem a inserção de nova linha podemos utilizar o método putc
este método coloca um carácter e cada vez. Assim encerramos o artigo com toda a informação básica necessária para trabalhar com ficheiros.