Ruby po kapkách (17.) – práce se soubory
V minulém díle jsme se zabývali základy vstupních a výstupních operací. Tentokrát se zaměříme na další podrobnosti ohledně práce se soubory. Nejdříve se však krátce podíváme na možná řešení úkolů z konce minulého dílu.
Prvním zadáním bylo vytvořit program, který spočítá kontrolní součet souboru. Pro zjednodušení nebudeme počítat žádnou skutečně používanou funkcí pro výpočet kontrolního součtu, ale spokojíme se s prostým součtem číselných hodnot jednotlivých bytů. Jedno z možných řešení může vypadat následovně.
suma = 0
File.open(ARGV[0]) do |f|
f.each_byte { |b| suma += b }
end
puts suma
Jak je vidět, otevíráme soubor, jehož název je interpretu předán jako první parametr. Jednotlivé byty jsou pak předávány do bloku, který je přičítá k proměnné, kde uchováváme aktuální součet. Použití vysokoúrovňových metod spolu s bloky nám ušetřilo práci s úkony typu uzavírání souboru nebo testování, zda jsem již dosáhli konce vstupu. Díky tomu, že Ruby bude automaticky upravovat požitelný rozsah celého čísla v proměnné suma (nakonec bude použita třída Fixnum
), bude tento triviální přístup fungovat i pro velké soubory. Použití programu na sebe sama vypadá takto:
~$ ruby chksum.rb chksum.rb
6643
Druhý příklad, který si klade za cíl porovnat navzájem dva soubory bude poněkud složitější. Ukážeme si co možná nejjednodušší řešení, ve kterém budeme ignorovat možnost vzniku chyb, protože bychom zatím stejně nevěděli, jak se s nimi vypořádat. Spokojíme se tedy s tím, že každá operace vstupu/výstupu, která skončí chybou zastaví běh programu, což je standardní chování.
f1 = File.new(ARGV[0])
f2 = File.new(ARGV[1])
result = ‚==‘
loop do
b1 = f1.getc
b2 = f2.getc
result = ‚!=‘ unless b1 == b2
break unless b1 and b2 and b1 == b2
end
f1.close
f2.close
puts „#{ARGV[0]} #{result} #{ARGV[1]}“
Otevíráme tentokrát zároveň dva soubory, jejichž jména zadáme jako první dva parametry příkazové řádky. Ve smyčce pak z obou souborů načteme po jednom bytu a pokud se byty nerovnají přenastavíme implicitní stav, že soubory jsou totožné. Následuje podmínka, která může ukončit smyčku v případě, kdy je jedna z hodnot b1 a b2 vyhodnocena jako false
nebo když se hodnoty nerovnají. Vzpoměňme si, že metoda getc
vrací nil
, když narazí na konec souboru, a že nil
se vyhodnocuje jako false
. Dále korektně uzavřeme oba soubory, i když v tomto případě, kdy program vzápětí končí bychom mohli spoléhat na to, že soubory uzavře operační systém po ukončení činnosti interpretu. Spuštění a porovnání sama se sebou a s jiným souborem vypadá následovně.
~$ ruby compare.rb compare.rb compare.rb
compare.rb == compare.rb
~$ ruby compare.rb compare.rb chksum.rb
compare.rb != chksum.rb
A nyní se již pojďme podívat na nové věci. Zatím jsme například všechny soubory otevírali jen pro čtení. Pokud bychom do nich chtěli zapisovat, musíme použít další parametr metody new
. Parametr je řetězec, který může obsahovat několik znaků s následujícím významem (který je převzat ze standardní knihovny jazyka C).
- r – otevření souboru pro čtení (implicitní volba)
- r+ – otevření pro čtení i zápis, začíná se na začátku souboru
- w – otevření jen pro zápis, kdy je soubor vytvořen nebo přepsán, pokud již existuje
- w+ – jako w, ale navíc i čtení
- a – jako w, ale soubor se nepřepíše, pokud existuje, začne se na konci souboru
- a+ – jako a, ale navíc i čtení
- b+ – binární mód na platformě MS Windows
Krátká relace v irb
demonstruje otevření souboru pro zápis a očíslování prvních deseti řádků. Při opakovaném spouštění by byl soubor vždy přepsán. Avšak pokud bychom změnili mód otevírání souboru na „a“, docházelo by k rozšiřování souboru o další řádky.
irb(main):001:0> f = File.new(‚test‘, ‚w‘)
=> #<File:test>
irb(main):002:0> 1.upto(10) { |i| f.puts i }
=> 1
irb(main):003:0> f.close
=> nil
Ve třídě File
je k dispozici řada metod pro zjišťování nebo nastavování různých vlastností souboru a pro manipulaci se soubory. Některé z těchto metod jsou metodami třídy, některé metodami instance a některé jsou dostupné v obou variantách. Pro podrobnější popis je třeba sáhnout po referenční příručce. My si ukážeme vybrané metody opět na příkladu relace v irb
.
irb(main):002:0> f = File.new(‚test‘, ‚w‘)
=> #<File:test>
irb(main):003:0> f.puts ‚bflmpsvz‘
=> nil
irb(main):004:0> f.atime
=> Thu Jul 16 21:25:53 +0200 2009
irb(main):005:0> f.mtime
=> Thu Jul 16 21:36:13 +0200 2009
irb(main):006:0> f.ctime
=> Thu Jul 16 21:36:13 +0200 2009
irb(main):007:0> f.close
=> nil
irb(main):008:0> File.atime(‚test‘)
=> Thu Jul 16 21:25:53 +0200 2009
irb(main):009:0> File.size(‚test‘)
=> 9
irb(main):010:0> File.truncate(‚test‘, 5)
=> 0
irb(main):011:0> File.size(‚test‘)
=> 5
irb(main):012:0> File.rename(‚test‘, ‚best‘)
=> 0
irb(main):013:0> File.delete(‚best‘)
=> 1
Na začátku opět vytvoříme soubor s názvem „test“. Série metod instance zjišťuje různé časy. Popořadě to je poslední čas přístupu k souboru, poslední čas modifikace souboru (obsahu) a čas poslední změny informací o souboru (v adresáři). Tyto metody jsou zároveň i metodami třídy, což je demonstrováno voláním metody File.atime
. U metod třídy je pochopitelně nutné zadávat jako první parametr cestu k souboru, na který se má operace aplikovat. Následuje metoda pro zjištění velikosti souboru v bytech a metoda pro zmenšení velikosti maximálně na daný počet bytů (zbytek je ztracen). Poslední dvě metody, jak již jejich názvy napovídají, slouží k přejmenování a smazání souborů.
Na různých platformách, kde je možné používat Ruby, se jako oddělovače adresářů v cestě k souboru používají buď normální nebo zpětná lomítka. Ruby proto má mechanismus pro přenositelnou konstrukci a dekonstrukci kompletní cesty. Oddělovač na dané platformě je uložen v konstantě File::SEPARATOR. Následující irb
relace pochází z unixového prostředí.
irb(main):001:0> File::SEPARATOR
=> „/“
irb(main):002:0> path = ‚/dir1/dir2/dir3/file‘
=> „/dir1/dir2/dir3/file“
irb(main):003:0> File.split(path)
=> [„/dir1/dir2/dir3“, „file“]
irb(main):004:0> File.dirname(path)
=> „/dir1/dir2/dir3“
irb(main):005:0> File.basename(path)
=> „file“
irb(main):006:0> File.join(‚dir‘, ‚subdir‘, ‚file‘)
=> „dir/subdir/file“
V příštím díle se budeme zabývat například možnostmi procházením adresářů. Již teď ale máme veškeré znalosti, abychom byli schopni vytvořit program pro kopírování souboru (cesta k extujícímu souboru a cesta ke kopii bude zadána jako parametr příkazové řádky). Konkrétní podobu programu ponecháme jako domácí úkol. Jako jistou inspiraci lze použít příklad s porovnáváním souborů.
Mohlo by vás také zajímat
-
Moderní trendy ve webdesignu: Top trendy pro rok 2024
12. ledna 2024 -
Jak si vyzkoušet Apple Intelligence v EU
2. srpna 2024 -
Windows App: Pracujte odkudkoliv, kdykoliv
3. listopadu 2024
Nejnovější
-
Jak chránit webové stránky před Web/AI Scrapingem
27. listopadu 2024 -
Jaký monitor je nejlepší k novému Macu Mini?
25. listopadu 2024 -
Výkonný a kompaktní: ASOME Max Studio s výjimečným poměrem cena/výkon
11. listopadu 2024 -
Šokující data od Microsoftu: Kyberútoky rostou o stovky procent!
8. listopadu 2024