2013-04-07 6 views
10

Czy można to zrobić?można utworzyć/zapisać/dołączyć ciąg do pliku w jednym wierszu w Ruby

v='some text' 
w='my' + Time.new.strftime("%m-%d-%Y").to_s + '.txt' 
File.write(w,v) # will create file if it doesn't exist and recreates everytime 

bez konieczności wykonywania File.open na wystąpieniu? Czy jest to tylko metoda klasy, która będzie albo dołączać, albo tworzyć i pisać? Idealnie rubinowy 1.9.3 soln.

thx

Edycja 1

oto co próbowałem w oparciu o dokumenty. Nie widziałem programu leczniczego, ale widziałem kilka innych przykładów. Ponownie pytam, jeśli to możliwe, aby otworzyć plik w trybie dodawania przez File.write? thx

irb(main):014:0> File.write('some-file.txt','here is some text',"a") 
TypeError: can't convert String into Integer 
    from (irb):14:in `write' 
    from (irb):14 
    from /usr/local/rvm/rubies/ruby-1.9.3-p392/bin/irb:13:in `<main>' 
irb(main):015:0> 


irb(main):015:0> File.write('some-file.txt','here is some text',O_APPEND) 
NameError: uninitialized constant O_APPEND 
    from (irb):15 
    from /usr/local/rvm/rubies/ruby-1.9.3-p392/bin/irb:13:in `<main>' 
irb(main):016:0> 
+3

soln. dzięki. Co za uprzejmy wyraz. – sawa

+0

Zawsze możesz zrobić coś w jednym wierszu, jeśli chcesz. – squiguy

+0

@sawa nie wiesz, co Cię denerwuje, no cóż, – timpone

Odpowiedz

37

Ruby była IO::write od 1.9.3. Twoja edycja pokazuje, że przekazujesz błędne argumenty. Pierwszy argument to nazwa pliku, drugi ciąg do zapisania, trzeci to opcjonalne przesunięcie, a czwarty to skrót, który może zawierać opcje do przejścia do otwartego. Ponieważ chcesz dołączyć, musisz zdać offset jako bieżący rozmiar pliku, aby skorzystać z tej metody:

File.write('some-file.txt', 'here is some text', File.size('some-file.txt'), mode: 'a') 

Ładunkowopodnoszą z wątku dyskusji: Metoda ta ma problemy współbieżności dla append ponieważ obliczenie offsetu jest z natury obce:. Ten kod najpierw znajdzie rozmiar X, otwórz plik, wyszukaj X i napisz. Jeśli inny proces lub wątek zapisuje do końca między File.size i szukaniem/pisaniem wewnątrz File::write, nie będziemy już dołączać i nadpisywać dane.

Jeśli otworzy się plik w trybie "a" i nie szuka, można na koniec napisać do semantyki POSIX zdefiniowanej dla fopen(3) with O_APPEND; więc polecam ten zamiast:

File.open('some-file.txt', 'a') { |f| f.write('here is some text') } 
+0

thx, wydaje się, że to robi. Nie jestem wielkim fanem tego kawałka ruby-api - po prostu naprawdę brzydki. Początkowo patrzyliśmy na to, aby poradzić sobie z problemami z wątkami przy użyciu składni blokowej, którą mamy z kodem napisanym jak @ennuikiller. Wątpię jednak, żeby to naprawiło. thx ponownie dla odpowiedzi, kiedy czytałem, że api docs pierwszy raz nie mogłem uwierzyć, że była składnia. – timpone

+0

@timpone Tak, przypadek użycia dla 'IO.write' jest miły dla semantyki create lub overwrite, ale niezręczny dla dołączenia. Może rozważyć rozszerzenie IO o 'class IO; def self.append (fn, str, opts = {}); IO.write (fn, str, File.size (fn), {mode: 'a'}. Merge (opts)); koniec; end' – dbenhur

+0

Ponownie myślę, że ten interfejs wieje do dołączenia w kontekście współbieżnym, ponieważ zawsze istnieje wyścig pomiędzy znalezieniem rozmiaru pliku i wydaniem zapisu. Myślę, że najlepiej będzie, jeśli otworzysz plik w trybie synchronizacji i pisania. – dbenhur

4
File.open('my' + Time.new.strftime("%m-%d-%Y").to_s + '.txt', 'w') { |file| file.write("some text") } 
+0

ok, jedno połączenie? thx – timpone

+3

To będzie zapisywać, ale nie dołączać, do pliku. Wierzę, że OP próbował dołączyć do pliku. Utwórz uchwyt pliku z "a", kiedy chcesz dołączyć. – thomax

2

MRI ma tę metodę już (dosłownie skopiowany i wklejony kod i to działa), ale ostatni raz sprawdzałem, JRuby i Rubinius nie. Być może teraz, nie mam ochoty instalować najnowszych wersji do obejrzenia.

http://rdoc.info/stdlib/core/IO.write

+0

thx za publikację, widziałem to i zaktualizowane pytanie z edycji 1.Próbowałem zapisać plik z "a", ale powiedziałem, że szuka int (który nie wydaje się być zgodny z rdoc), a następnie wypróbował standardową stałą UNIX, ale też tego nie lubi. Naprawdę, po prostu szukam, czy ta składnia jest możliwa. Nie wiem, dlaczego wszystkie pomyłki. – timpone

+0

Jeśli skopiujesz i wkleisz i zadziałało, twój rubin jest zepsuty. Problem z jego wywołaniem polega na tym, że trzeci argument ma być offsetem całkowitym, a nie trybem pliku. – dbenhur

+0

thx - edycja nr 1 była następstwem tej odpowiedzi – timpone

7

Żeby było jasne, jak niektóre komentarze sugerują testowałem tej pracy: IO.write("/tmp/testfile", "gagaga\n", mode: 'a')

To jeden dołącza do pliku bez potrzeby obliczania offsetu. Rubydoc jest trochę mylący. Oto błąd na ten temat: https://bugs.ruby-lang.org/issues/11638

Powiązane problemy