Aula 16
Como fazer IO (Input / Output) básico em Ruby.
file = File.open("arquivo.txt", "r") #processa arquivo file.close File.open("arquivo", "r") do |file| #processa arquivo end file = open("arquivo", "r") ...
r | Read-only, starts at beginning of file (default mode). |
r+ | Read/write, starts at beginning of file. |
w | Write-only, truncates an existing file to zero length or creates a new file for writing. |
w+ | Read/write, truncates existing file to zero length or creates a new file for reading and writing. |
a | Write-only, starts at end of file if file exists; otherwise creates a new file for writing. |
a+ | Read/write, starts at end of file if file exists; otherwise creates a new file for reading and writing. |
b | (DOS/Windows only) Binary file mode (may appear with any of the key letters listed above). |
Os métodos puts
, putc
, gets
, getc
, printf
(presentes em Kernel) são todos métodos da classe IO.
in_f = File.open("entrada.txt", "r") out = File.open("saida.txt", "w+") count = 1 while(linha = in_f.gets) out.printf "%10d - %s", count, linha count += 1 end in_f.close; out.close
IO#puts
, IO#putc
, IO#gets
, IO#getc
, IO#printf
, IO#print
, IO#write
IO.read(filename) -> string
IO.readlines(filename) -> array
IO#eof?
, IO#lineno
, IO#pos
, IO#pos=
, IO#rewind
, IO#seek
file = open('texto.txt', 'r') file.pos = 10 file.gets # => file.seek(10) # equivalente a file.pos = 10 e file.seek(10, IO::SEEK_SET) file.gets # => file.seek(10, IO:SEET_CUR) # avança 10 da atual file.gets # => file.seek(-10, IO:SEET_END) # 10 antes do fim file.gets # => file.close
open("texto.txt", "r+") do |file| primeira_linha = file.gets primeiro_c_seg_linha = file.getc seg_linha = file.gets file.seek(-10, IO::SEEK_END) array_of_lines = file.readlines file.seek(-10, IO::SEEK_END) file.puts("substitui últimos 10 chars") file.rewind char = file.getc file.seek(0, IO::SEEK_END) file.putc(char) end
São simples inteiros, de 0 a 255. #getc
lê um caractere e #putc
escreve caractere.
c = $stdin.getc # aguarda leitura do caractere $stdout.puts c #recebe inteiro e imprime o caractere correspondente "um string"[3] # => 115 - caractere "s"
A entrada padrão, saída padrão, e saída de erro padrão são objetos IO. Redirecionando a saída:
def out_to_file(out_f_name) terminal= $stdout file_out= open(out_f_name, "w+") $stdout = file_out yield ensure file_out.close $stdout = terminal end out_to_file("saida.txt") do puts "tudo feito aqui vai para saida.txt" end puts "aqui vai para o terminal"
IO#each_byte |
Itera byte a byte (8 bits). Passa char (inteiro de 0 a 255) como parâmetro do bloco. |
IO#each_line ou IO#each |
Itera linha a linha. Passa a linha (String) como parâmetro do bloco. |
IO.foreach |
Abre arquivo e itera linha a linha, de uma vez só. |
in_f = File.open("entrada.txt", "r") out = File.open("saida.txt", "w+") in_f.each_with_index do |line, index| out.printf "%10d - %s", index + 1, line end in_f.close; out.close
out = File.open("saida.txt", "w+") count = 1 IO.foreach("entrada.txt") do |line| out.printf("%10d - %s", count, line) count += 1 end out.close
in_f = File.open("entrada.txt", "r") out = File.open("saida.txt", "w+") in_f.inject(1) do |count, line| out.printf("%10d - %s", count, line) count + 1 end in_f.close; out.close
Uma classe que permite usar um objeto de IO que escreve/le em um String. Útil em testes.
require 'stringio' ip = StringIO.new("now is\nthe time\nto learn\nRuby!") op = StringIO.new("", "w") ip.each_line do |line| op.puts line.reverse end op.string → "\nsi won\n\nemit eht\n\nnrael ot\n!ybuR\n"
O protocolo TCP é o mais popular da internet. É o que vai ser utilizado no lab 6.
require 'socket' client = TCPSocket.open('127.0.0.1', 'finger') client.send("mysql\n", 0) # 0 means standard packet puts client.readlines client.close
Aceita conexões (permite criação de servidores).
require 'socket' server = TCPServer.new('localhost', 80) while (session = server.accept) puts "Request: #{session.gets}" session.print "HTTP/1.1 200/OK\r\nContent-type: text/html\r\n\r\n" session.print "<html><body><h1>#{Time.now}</h1></body></html>\r\n" session.close end
Conversam com protocolos na camada de aplicação (nível mais alto que o TCP):
require 'net/http' h = Net::HTTP.new('www.pragmaticprogrammer.com', 80) response = h.get('/index.html', nil) if response.message == "OK" puts response.body.scan(/<img src="(.*?)"/m).uniq end
Biblioteca que extende o Kernel#open
para para abrir URIs (ou URLs). Segue redirecionamentos e age como um cliente HTTP/FTP completo.
require 'open-uri' open('http://www.pragmaticprogrammer.com') do |f| puts f.read.scan(/<img src="(.*?)"/m).uniq end
É um padrão simples “legível por humanos” para serialização de estruturas de dados. Suporta arrays, hashes e OO em geral. Bibliotecas disponíveis nas mais diversas linguagens.
require 'yaml' tree = { :name => 'ruby', :uses => [ 'scripting', 'web', 'testing', 'etc' ] } File.open("tree.yml", "w") {|f| YAML.dump(tree, f)}
require 'yaml' tree = YAML.load(File.open("tree.yml")) tree[:uses][1] → "web"
class Aluno attr_accessor :nome, :professor end class Professor attr_accessor :nome end a = Aluno.new p = Professor.new p.nome = "Marcelo" a.nome = "Joao" a.professor = p File.open("aluno.yml", "w") {|f| f.puts(a.to_yaml) }