Як записати файл у Ruby?


572

Мені потрібно прочитати дані з бази даних, а потім зберегти їх у текстовому файлі.

Як я можу це зробити в Ruby? Чи є в Ruby система управління файлами?

Відповіді:


179

Рубіновий клас файлу дасть вам всі входи і виходи ::newі , ::openале його батько, клас IO , потрапить в глибину #readі #write.


6
Дякую @Geoff. Добре бачити нових користувачів, які прибирають застарілі запитання та відповіді. Покращує загальний сайт.
jdl

7
Я вважаю це іронічним. Відповідь дуже добре задокументована ... але зараз через рік це питання є першим зверненням до Google. Коли питання було задано, можливо, здавалося, що ОП докладає мало зусиль, але зараз, що стосується Google, це найкраще джерело.
Джефф

7
Напевно, тому, що тут все, що потрібно насправді знати. Моя відповідь "навчити людину ловити рибу" для тих, хто хоче читати дрібніші деталі, і тут є безліч відповідей "дай людині рибу", а також людям, які просто хочуть різати і вставляти. Не дивно, що ця комбінація в кінцевому підсумку займає чітке місце в Google.
jdl

1
Тож, чесно кажучи, я працюю на безлічі різних мов, а це означає, що мені рідко подобається згадувати синтаксис для будь-якої конкретної. Я кілька разів переглядав це, і я завжди прокручую прямо повз цю відповідь, до тієї, що знаходиться під нею, тому що коли я google StackOverflow, я просто шукаю рибу, що боїться. : p Чесно кажучи, це добре мати обоє. Можливо, колись я зроблю достатньо Рубі відразу всіх, що я буду дбати про деталі.
user435779

2
Це не дає відповіді на запитання. Він просто вказує на два класи, які містять більшість методів здійснення вводу-виводу і не згадує про зв'язок із базою даних. Це було б добре як коментар, але навряд чи кваліфікується як відповідь. Я розумію, що ОП та багато читачів, які підтримали цю відповідь, не погоджуються, і я відверто не розумію, що вони думали.
Cary Swoveland

929

Ви шукаєте наступне?

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

8
yourfile- це змінна, яка містить ім'я файла, який потрібно записати.
B Сім

17
Як варіант: f = File.open ('ім'я', 'w'); f.write ('текст'); f.close
vish

5
@vish: Я б не рекомендував це рішення, оскільки дескриптор файлу залишатиметься відкритим, якщо f.writeвідкриється виняток.
nbarraille

288
Коротке та солодке:File.write('filename', 'content')
Бенджамін Оукс

14
Ще коротше і задокументовано:IO.write('filename', 'content')
Тайська

636

Ви можете використовувати коротку версію:

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

Він повертає записану довжину; див . : написати для отримання детальної інформації та опцій.

Щоб додати файл, якщо він вже існує, використовуйте:

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

14
FYI цей скорочений метод працює лише починаючи з Ruby 1.9.3. Немає такого способу в жодних попередніх версіях 1.9 або 1.8. У цьому випадку ви повинні використовувати метод більш тривалого блоку, опублікований @mvndaai
Ендрю Бернс

13
FYI це правильно закриває файл після його закінчення.
Freedom_Ben

2
Документи IO класу кажуть, що це закриває файл
nruth

7
Чи додасть це файл або просто його перезапише?
Джошуа Пінтер

8
@JoshPinter: це перезаписується.
mklement0

248

Це переважний підхід у більшості випадків:

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

При передачі блоку File.openоб'єкт File автоматично закриється, коли блок припиняється.

Якщо ви не переходите до блоку File.open, ви повинні переконатися, що файл правильно закритий, а вміст записаний у файл.

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

Ви можете знайти його в документації :

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;
}

Так, використовуючи синтаксис блоку з {| файлом | ....} закриє файл, коли блок закриється.
wesgarrison

Класно, спасибі. Я не був у цьому впевнений. Ось додаткова інформація про блоки та File.open blog.rubybestpractices.com/posts/rklemme/… це також згадується в офіційній документації
Tombart

1
Просто щось рубінове: ish - це об'єкт, тому, щоб перевірити, чи недійсний файл, ви запитаєте сам об'єкт замість порівняння (file.nil? Замість file == nil)
JCabello

@JCabello впевнений, що це, безумовно, більше як Рубі підхід, дякую!
Томбарт

нарешті відповідь, яка показує, що слід також перевірити стан файлів і як з ним поводитися, а не лише один вкладиш, який просто показує відкритий виклик.
Насер

115

Відповідь Замбрі , знайдена тут , найкраща.

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

де ваші варіанти <OPTION> :

r- Лише для читання. Файл повинен існувати.

w - Створіть порожній файл для запису.

a - Додайте до файлу. Файл створюється, якщо його не існує.

r+- Відкрийте файл для оновлення як для читання, так і для запису. Файл повинен існувати.

w+ - Створіть порожній файл як для читання, так і для запису.

a+- Відкрийте файл для читання та додавання. Файл створюється, якщо його не існує.

У вашому випадку wкраще.


Я шалений, що відповідь, яка, мабуть, копіює іншу відповідь, може отримати понад 100 голосів. Я бачу розміщення першого речення як коментар до питання, але це все.
Cary Swoveland

@CarySwoveland Я фактично з вами згоден. Справжня проблема полягає в тому, що одне з двох питань давно повинно було бути позначене як дублікат. Я скопіював відповідь, бо одного разу, коли знайшов запитання, на який відповів zanbri, і наступні кілька разів, коли мені потрібна була та сама інформація, я спочатку натрапив на це питання і мусив з’ясувати, як дійти до іншого питання. Врешті-решт, я подумав, що тут просто буде простіше мати його відповідь. Я пов'язував його відповідь так сподіваюсь, що люди натиснуть і також дадуть йому нагороду.
mvndaai

31

Для тих із нас, хто вчиться на прикладі ...

Введіть текст у такий файл:

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

БОНУСНА ІНФОРМАЦІЯ ...

Прочитайте так назад

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

Часто мені хочеться прочитати файл у своєму буфері обміну ***

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

В інший час я хочу написати те, що є в буфері обміну, у файл ***

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

*** Припускає, що у вас встановлений самоцвіт буфера обміну

Дивіться: https://rubygems.org/gems/clipboard


1
Остерігайтеся IO.writeопції замінити вміст файлу, а не додавати. Додавання з IO.write трохи нудно.
fguillen

Не знаєте, про що ви говорите? Команда IO.write не потребує цієї опції для запису у файл. Я був би обережний або зберегти файл у каталозі / tmp або поточному каталозі; В іншому випадку ви можете побачити Errno::ENOENT: No such file or directory @ rb_sysopenповідомлення та створений файл розміром 0 байт.
l3x

25

Щоб знищити попередній вміст файлу, тоді напишіть у нього новий рядок:

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

Щоб додати до файлу, не перезаписуючи його старий вміст:

open('myfile.txt', "a") { |f| f << 'I am appended string' } 
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.