Jak pisać do pliku w Ruby?


571

Muszę odczytać dane z bazy danych, a następnie zapisać je w pliku tekstowym.

Jak mogę to zrobić w Ruby? Czy w Ruby jest system zarządzania plikami?

Odpowiedzi:


178

Klasa Ruby File da ci tajniki ::newi, ::openale jej rodzic, klasa IO , wchodzi w głębokość #readi #write.


6
Dzięki @Geoff. Dobrze jest widzieć, jak nowi użytkownicy usuwają nieaktualne pytania i odpowiedzi. Sprawia, że ​​ogólnie lepsza strona.
jdl

7
Uważam to za ironię. Odpowiedź jest bardzo dobrze udokumentowana ... ale teraz rok później to pytanie jest pierwszym hitem w Google. Kiedy pytanie zostało zadane, mogło się wydawać, że PO poświęca niewiele wysiłku, ale teraz, jeśli chodzi o Google, jest to najlepsze źródło.
Jeff

7
Prawdopodobnie dlatego, że wszystko, co naprawdę musisz wiedzieć, jest tutaj. Moim jest odpowiedź „naucz człowieka łowić ryby” dla tych, którzy chcą przeczytać drobniejsze szczegóły, i jest tu mnóstwo odpowiedzi „daj człowiekowi rybę” również dla osób, które po prostu chcą wycinać i wklejać. Nic dziwnego, że ta kombinacja kończy się dobrą pozycją w Google.
jdl

1
Tak więc, uczciwie, pracuję w wielu różnych językach, co oznacza, że ​​rzadko zapominam o składni dla dowolnego konkretnego. Przeszukałem to kilka razy i zawsze przewijam tuż obok tej odpowiedzi, do tej pod nią, ponieważ kiedy google StackOverflow zwykle szukam po prostu ryby dang. : p Szczerze mówiąc, dobrze jest mieć oba. Być może kiedyś zrobię tyle Ruby naraz, że będę dbał o szczegóły.
user435779,

2
To nie odpowiada na pytanie. Wskazuje jedynie na dwie klasy, które zawierają większość metod wykonywania operacji we / wy, i nie wspomina o połączeniu z bazą danych. To byłoby w porządku jako komentarz, ale prawie nie kwalifikuje się jako odpowiedź. Zdaję sobie sprawę, że OP i wielu czytelników, którzy głosowali tę odpowiedź, nie zgadzają się i szczerze mówiąc, nie rozumiem, o czym myśleli.
Cary Swoveland

929

Czy szukasz następujących rzeczy?

File.open(yourfile, 'w') { |file| file.write("your text") }

8
yourfileto zmienna przechowująca nazwę pliku do zapisania.
B, 7

17
Alternatywnie: f = File.open ('name', 'w'); f.write („tekst”); f.close
vish

5
@vish: Nie poleciłbym tego rozwiązania, ponieważ deskryptor pliku byłby otwarty, gdyby f.writepojawił się wyjątek.
nbarraille

288
Krótka i słodka:File.write('filename', 'content')
Benjamin Oakes,

14
Jeszcze krótszy i udokumentowany:IO.write('filename', 'content')
tajski

636

Możesz użyć krótkiej wersji:

File.write('/path/to/file', 'Some glorious content')

Zwraca zapisaną długość; zobacz :: napisz po więcej szczegółów i opcji.

Aby dołączyć do pliku, jeśli już istnieje, użyj:

File.write('/path/to/file', 'Some glorious content', mode: 'a')

14
Do Twojej wiadomości ta skrócona metoda działa tylko począwszy od Ruby 1.9.3. Nie ma takiej metody we wcześniejszych wersjach 1.9 lub 1.8. W takim przypadku musisz użyć dłuższej metody blokowania opublikowanej przez @mvndaai
Andrew Burns

13
FYI to poprawnie zamyka plik po zakończeniu.
Freedom_Ben


7
Czy to doda się do pliku, czy po prostu nadpisze?
Joshua Pinter,

8
@JoshPinter: nadpisuje.
mklement0

248

Jest to preferowane podejście w większości przypadków:

 File.open(yourfile, 'w') { |file| file.write("your text") }

Po przekazaniu bloku File.openobiekt File zostanie automatycznie zamknięty po jego zakończeniu.

Jeśli nie przekażesz bloku File.open, musisz upewnić się, że plik jest poprawnie zamknięty, a treść została zapisana w pliku.

begin
  file = File.open("/tmp/some_file", "w")
  file.write("your text") 
rescue IOError => e
  #some error occur, dir not writable etc.
ensure
  file.close unless file.nil?
end

Można go znaleźć w dokumentacji :

static VALUE rb_io_s_open(int argc, VALUE *argv, VALUE klass)
{
    VALUE io = rb_class_new_instance(argc, argv, klass);
    if (rb_block_given_p()) {
        return rb_ensure(rb_yield, io, io_close, io);
    }
    return io;
}

Tak, używając składni bloku z {| file | ....} zamknie plik po zamknięciu bloku.
wesgarrison,

Fajne dzięki. Nie byłem tego pewien. Oto kilka dodatkowych informacji na temat bloków i File.open blog.rubybestpractices.com/posts/rklemme/… jest również wspomniany w oficjalnej dokumentacji
Tombart

1
Po prostu coś rubinowego: zero jest obiektem, więc aby sprawdzić, czy plik jest pusty, pytasz sam obiekt zamiast porównywania (file.nil? Zamiast file == zero)
JCabello

@JCabello, jasne, to zdecydowanie bardziej rubinowe podejście, dzięki!
Tombart

wreszcie odpowiedź, która pokazuje, że należy również sprawdzić status pliku i sposób jego obsługi, a nie tylko jedną linijkę, która pokazuje tylko otwarte połączenie.
Nasser

115

Znaleziona tutaj odpowiedź Zambri jest najlepsza.

File.open("out.txt", '<OPTION>') {|f| f.write("write your stuff here") }

gdzie twoje opcje <OPTION>to:

r- Tylko czytać. Plik musi istnieć.

w - Utwórz pusty plik do pisania.

a - Dołącz do pliku. Plik zostanie utworzony, jeśli nie istnieje.

r+- Otwórz plik, aby zaktualizować zarówno odczyt, jak i zapis. Plik musi istnieć.

w+ - Utwórz pusty plik do odczytu i zapisu.

a+- Otwórz plik do odczytu i dołączenia. Plik zostanie utworzony, jeśli nie istnieje.

W twoim przypadku wjest preferowane.


Dziwię się, że odpowiedź, która wprawdzie kopiuje inną odpowiedź, może otrzymać ponad 100 głosów pozytywnych. Widzę opublikowanie pierwszego zdania jako komentarza do pytania, ale to wszystko.
Cary Swoveland

@CarySwoveland Zgadzam się z tobą. Prawdziwy problem polega na tym, że jedno z dwóch pytań powinno być oznaczone dawno temu jako duplikat. Skopiowałem odpowiedź, ponieważ kiedy znalazłem pytanie, na które zanbri odpowiedział, a kilka razy, kiedy potrzebowałem tych samych informacji, natknąłem się na to pytanie najpierw i musiałem wymyślić, jak przejść do drugiego pytania. W końcu pomyślałem, że łatwiej będzie mieć tutaj również jego odpowiedź. Mam nadzieję, że połączyłem się z jego odpowiedzią, ludzie też kliknęliby na niego i oddali mu głos.
mvndaai

31

Dla tych z nas, którzy uczą się na przykładach ...

Napisz tekst do pliku takiego jak ten:

IO.write('/tmp/msg.txt', 'hi')

INFORMACJE O BONUSIE ...

Przeczytaj to w ten sposób

IO.read('/tmp/msg.txt')

Często chcę czytać plik w moim schowku ***

Clipboard.copy IO.read('/tmp/msg.txt')

A innym razem chcę zapisać zawartość mojego schowka do pliku ***

IO.write('/tmp/msg.txt', Clipboard.paste)

*** Zakłada, że ​​masz zainstalowany klejnot schowka

Zobacz: https://rubygems.org/gems/clipboard


1
Uwaga: IO.writeopcja zastępowania zawartości pliku zamiast dołączania. Dołącz z IO.write jest trochę nudne.
fguillen

Nie jesteś pewien, o czym mówisz? Polecenie IO.write nie potrzebuje tej opcji do zapisu do pliku. Byłbym ostrożny albo zapisać plik w katalogu / tmp lub w bieżącym katalogu; W przeciwnym razie może zostać wyświetlony Errno::ENOENT: No such file or directory @ rb_sysopenkomunikat i plik utworzony o rozmiarze 0 bajtów.
l3x

25

Aby zniszczyć poprzednią zawartość pliku, wpisz nowy ciąg do pliku:

open('myfile.txt', 'w') { |f| f << "some text or data structures..." } 

Aby dołączyć do pliku bez nadpisywania jego starej zawartości:

open('myfile.txt', "a") { |f| f << 'I am appended string' } 
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.