W większości języków programowania powszechnie wiadomo, że praca z plikami przebiega w trybie open-use-close. Jednak wiele razy widziałem w kodach ruby niezrównane wywołania File.open, a ponadto znalazłem ten klejnot wiedzy w dokumentach ruby:
Strumienie we / wy są automatycznie zamykane, gdy są zajęte przez moduł odśmiecania pamięci.
darkredandyellow przyjazny irc zajmuje się problemem:
[17:12] tak, a także liczba deskryptorów plików jest zwykle ograniczona przez system operacyjny
[17:29] Zakładam, że można łatwo zabraknąć dostępnych deskryptorów plików, zanim garbage collector wyczyści w górę. w takim przypadku możesz użyć zamknij je samodzielnie. „zgłoszony przez śmieciarza”. oznacza, że GC zacznie działać w pewnym momencie w przyszłości. i jest drogi. wiele powodów do jawnego zamykania plików.
- Czy musimy wyraźnie zamknąć
- Jeśli tak, to dlaczego GC automatycznie się zamyka?
- Jeśli nie, to po co?
$ ulimit -n => 1024
jest wysoki tylko wtedy, gdy wykonujesz prostą pracę. Zły nawyk pewnego dnia spowoduje duży problem!Odpowiedzi:
Czy możesz podać przykład? Widzę to tylko w kodzie napisanym przez początkujących, którzy nie mają „powszechnej wiedzy w większości języków programowania, że przepływ pracy z plikami jest otwarty-użyj-zamknij”.
Doświadczeni rubiniści albo jawnie zamykają swoje pliki, albo, bardziej idiomatycznie, używają formy blokowej
File.open
, która automatycznie zamyka plik za Ciebie. Jego implementacja w zasadzie wygląda mniej więcej tak:def File.open(*args, &block) return open_with_block(*args, &block) if block_given? open_without_block(*args) end def File.open_without_block(*args) # do whatever ... end def File.open_with_block(*args) yield f = open_without_block(*args) ensure f.close end
Skrypty to szczególny przypadek. Skrypty zazwyczaj działają tak krótko i używają tak niewielu deskryptorów plików, że po prostu nie ma sensu ich zamykać, ponieważ system operacyjny i tak je zamknie, gdy skrypt zakończy działanie.
Tak.
Ponieważ po zebraniu obiektu nie ma już możliwości zamknięcia pliku, a tym samym wyciekułoby deskryptory plików.
Zauważ, że to nie garbage collector zamyka pliki. Moduł odśmiecania pamięci po prostu wykonuje finalizatory dla obiektu, zanim go zbierze. Tak się składa, że
File
klasa definiuje finalizator, który zamyka plik.Ponieważ zmarnowana pamięć jest tania, ale zmarnowane deskryptory plików nie. Dlatego nie ma sensu wiązać czasu życia deskryptora pliku z czasem życia jakiegoś fragmentu pamięci.
Po prostu nie można przewidzieć, kiedy będzie działać odśmiecacz. Nie można jeszcze przewidzieć, czy to będzie działać w ogóle : jeśli nigdy nie zabraknie pamięci, garbage collector nigdy nie zabraknie, dlatego finalizator nigdy nie zabraknie, więc plik nigdy nie zostanie zamknięta.
źródło
ensure
,rescue
iraise
nie są w ogóle konieczne.ensure
bezrescue
. I nie możesz po prostu cicho połknąć wyjątku, musisz go przekazać wywołującemu po zamknięciu pliku. W każdym razie, przypomnij mi ponownie w maju '15 :-DPo użyciu należy zawsze zamknąć deskryptory plików, co również spowoduje jego opróżnienie. Często ludzie używają File.open lub równoważnej metody z blokami do obsługi okresu istnienia deskryptora pliku. Na przykład:
File.open('foo', 'w') do |f| f.write "bar" end
W tym przykładzie plik jest zamykany automatycznie.
źródło
Według http://ruby-doc.org/core-2.1.4/File.html#method-c-open
Dlatego zostanie automatycznie zamknięty po zakończeniu blokady : D
źródło
źródło
Możemy użyć
File.read()
funkcji do odczytania pliku w Rubim ..... takiej jak,file_variable = File.read("filename.txt")
w tym przykładzie
file_variable
może mieć pełną wartość tego pliku ....źródło