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.