จะเขียนเป็นไฟล์ใน Ruby ได้อย่างไร?


572

ฉันต้องการอ่านข้อมูลจากฐานข้อมูลแล้วบันทึกลงในไฟล์ข้อความ

ฉันจะทำอย่างนั้นใน Ruby ได้อย่างไร มีระบบจัดการไฟล์ใน Ruby หรือไม่?

คำตอบ:


179

ทับทิมคลาแฟ้มจะทำให้คุณ ins ลึกหนาบางของ::newและ::openแต่แม่ของมันที่ระดับ IO , ได้รับในเชิงลึกของและ#read#write


6
ขอบคุณ @Geoff เป็นการดีที่ได้เห็นผู้ใช้รายใหม่ทำความสะอาดคำถามและคำตอบที่ล้าสมัย ทำให้ไซต์โดยรวมดีขึ้น
jdl

7
ฉันพบว่าแดกดันนี้ คำตอบนั้นได้รับการบันทึกไว้เป็นอย่างดี ... แต่ตอนนี้อีกหนึ่งปีต่อมาคำถามนี้เป็นคำถามแรกใน Google เมื่อมีการถามคำถามอาจดูเหมือนว่า OP ได้อุทิศความพยายามเล็กน้อย แต่ตอนนี้เท่าที่ Google กังวลนี่คือแหล่งที่ดีที่สุด
Jeff

7
อาจเป็นเพราะทุกสิ่งที่คุณจำเป็นต้องรู้อยู่ที่นี่ ของฉันคือคำตอบที่ "สอนคนตกปลา" สำหรับผู้ที่ต้องการอ่านรายละเอียดปลีกย่อยและมีคำตอบมากมายที่ "ให้ปลาแก่ผู้ชาย" ที่นี่เช่นกันสำหรับผู้ที่ต้องการตัดและวาง ไม่น่าแปลกใจที่ชุดค่าผสมนี้จะสิ้นสุดลงในอันดับที่ดีบน Google
jdl

1
ดังนั้นในความเป็นธรรมฉันทำงานในภาษาต่าง ๆ มากมายซึ่งหมายความว่าฉันไม่ค่อยได้จดจำเกี่ยวกับไวยากรณ์สำหรับภาษาใดภาษาหนึ่ง ฉันไปที่นี่สองสามครั้งและฉันมักจะเลื่อนผ่านคำตอบนี้ไปที่ด้านล่างเพราะเมื่อฉัน google StackOverflow ฉันมักจะมองหาปลาแดง : p จริง ๆ แล้วมันก็ดีทั้งคู่ บางทีสักวันหนึ่งฉันจะทำทับทิมมากพอในครั้งเดียวเพื่อที่ฉันจะใส่ใจในรายละเอียด
user435779

2
นี่ไม่ได้ตอบคำถาม มันชี้ไปที่คลาสสองคลาสที่มีวิธีการทำ I / O เกือบทั้งหมดและไม่ได้กล่าวถึงการเชื่อมต่อกับฐานข้อมูล นั่นอาจเป็นความคิดเห็นที่ดี แต่แทบจะไม่ถือว่าเป็นคำตอบ ฉันรู้ว่า OP และผู้อ่านหลายคนที่ตอบโต้คำตอบนี้ไม่เห็นด้วยและฉันไม่เข้าใจสิ่งที่พวกเขาคิด
Cary Swoveland

929

คุณกำลังมองหาสิ่งต่อไปนี้หรือไม่?

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

8
yourfileเป็นตัวแปรที่เก็บชื่อของไฟล์ที่จะเขียน
B เซเว่น

17
อีกทางเลือกหนึ่ง: f = File.open ('name', 'w'); f.write ( 'ข้อความ'); f.close
vish

5
@ วิช: ฉันจะไม่แนะนำวิธีแก้ปัญหานี้เนื่องจากตัวอธิบายไฟล์จะเปิดทิ้งไว้หากf.writeมีข้อยกเว้น
nbarraille

288
สั้นและหวาน:File.write('filename', 'content')
Benjamin Oakes

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
Andrew Burns

13
FYI สิ่งนี้จะปิดไฟล์อย่างถูกต้องเมื่อเสร็จสิ้น
Freedom_Ben

2
เอกสารระดับ IOบอกว่าจะปิดไฟล์
nruth

7
สิ่งนี้จะผนวกเข้ากับไฟล์หรือเขียนทับมันได้หรือไม่
Joshua Pinter

8
@JoshPinter: มันเขียนทับ
mklement0

248

วิธีนี้เป็นวิธีที่แนะนำในกรณีส่วนใหญ่:

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

เมื่อบล็อกถูกส่งผ่านไปยังFile.openวัตถุไฟล์จะถูกปิดโดยอัตโนมัติเมื่อบล็อกสิ้นสุดลง

หากคุณไม่ผ่านการบล็อก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;
}

ใช่ใช้ไวยากรณ์บล็อกด้วย {| file | .... } จะปิดไฟล์เมื่อปิดบล็อก
wesgarrison

เจ๋งขอบคุณ ฉันไม่แน่ใจเกี่ยวกับเรื่องนั้น ต่อไปนี้เป็นข้อมูลเพิ่มเติมเกี่ยวกับบล็อกและFile.open blog.rubybestpractices.com/posts/rklemme/ …มันยังกล่าวถึงในเอกสารอย่างเป็นทางการ
Tombart

1
เพียงแค่บางสิ่งบางอย่าง ruby ​​way-ish: nil เป็นวัตถุดังนั้นเพื่อตรวจสอบว่าไฟล์เป็นโมฆะหรือไม่คุณต้องถามวัตถุเองแทนที่จะทำการเปรียบเทียบ (file.nil? แทนที่จะเป็นไฟล์ == ไม่มี)
JCabello

@JCabello แน่ใจว่านั่นเป็นวิธีที่เหมือนทับทิมมากกว่าแน่นอนขอบคุณ!
Tombart

ในที่สุดคำตอบที่แสดงว่าควรตรวจสอบสถานะไฟล์และวิธีจัดการกับมันด้วยไม่ใช่แค่สายการบินเดียวที่แสดงการโทรที่เปิดอยู่
Nasser

115

คำตอบของแซมเบียที่พบที่นี่ดีที่สุด

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

ตัวเลือกของคุณ<OPTION>คือ:

r- อ่านเท่านั้น. ไฟล์จะต้องมีอยู่

w - สร้างไฟล์ว่างเปล่าสำหรับการเขียน

a - ต่อท้ายไฟล์ไฟล์จะถูกสร้างขึ้นหากไม่มีอยู่

r+- เปิดไฟล์สำหรับอัพเดตทั้งการอ่านและการเขียน ไฟล์จะต้องมีอยู่

w+ - สร้างไฟล์ว่างสำหรับทั้งการอ่านและการเขียน

a+- เปิดไฟล์สำหรับอ่านและต่อท้าย ไฟล์ถูกสร้างขึ้นหากไม่มีอยู่

ในกรณีของคุณwจะดีกว่า


ฉันเซที่คำตอบที่คัดลอกคำตอบอื่นที่ยอมรับได้รับมากกว่า 100 upvotes ฉันสามารถเห็นการโพสต์ประโยคแรกเป็นความคิดเห็นในคำถาม แต่นั่นมัน
Cary Swoveland

@CarySwoveland ฉันเห็นด้วยกับคุณจริงๆ ปัญหาที่แท้จริงคือว่าหนึ่งในสองคำถามควรถูกทำเครื่องหมายว่าซ้ำกันมานานแล้ว ฉันคัดลอกคำตอบเพราะเมื่อฉันพบคำถามที่ zanbri ได้ตอบและไม่กี่ครั้งถัดไปเมื่อฉันต้องการข้อมูลเดียวกันที่ฉันเจอคำถามนี้ก่อนและต้องคิดหาวิธีที่จะได้คำถาม ในที่สุดฉันคิดว่ามันจะง่ายกว่าที่จะได้คำตอบของเขาที่นี่เช่นกัน ฉันเชื่อมโยงกับคำตอบของเขาดังนั้นหวังว่าผู้คนจะคลิกมากกว่าและให้ upvote เขาเช่นกัน
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' } 
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.