Ruby - Creating a file in memory
Asked Answered
B

5

26

Is there anyway to write the following code in Ruby without writing the file to disk?

temp_file = 'path/to/file.csv'
users = [[email protected], [email protected]]

CSV.open(temp_file, "w") do |csv|
  csv << data_for_report
end

Reports.sendreport users temp_file

File.delete(temp_file)

The Reports.sendreport attaches a file and sends an email, so it needs to be a file...

Briannebriano answered 23/1, 2013 at 20:27 Comment(5)
So you want a string of comma separated values? Do you need the csv at that point? Could you join your columns with commas, and your rows with newlines?Catha
Ohh, the sendreport function sends a mail with a csv-file attached. So I really need it to be a file...Briannebriano
Are you saying the sendreport method reads the file from disk?Catha
Correct.. It reads a file from disc and attaches it to an email. The question now is if there is anyway to save the file, as a file, in memory.Briannebriano
If you can't change Reports, then you probably are doing it the right way. It's probably more trouble than it's worth to get a section of memory to pretend it's a disk so Reports can read from it.Catha
B
2

Try one of the mmap gems. If the library only takes a filename, that's your option.

If it can accept a file-like object, however, you can use a StringIO.

You might consider changing whatever Reports is, making it more general-purpose. It depends on what it's using to create its mail message–this might be trivial.

Brittaneybrittani answered 23/1, 2013 at 21:12 Comment(1)
I will look into StringIO, think that might be what I am looking for... Reports.sendreport is really just my own wrapper on the gmail gem, so I am not really sure if i need a real if or if StringIO will work.Briannebriano
S
21

You could use Tempfile. Tempfile writes the file to disc, so it does not fit your request.

But I think Tempfile provides some features you need:

When a Tempfile object is garbage collected, or when the Ruby interpreter exits, its associated temporary file is automatically deleted.

Example:

require 'tempfile'
require 'csv'

data_for_report = [1,2,3,4]
temp_file = Tempfile.new('foo')

CSV.open(temp_file, "w") do |csv|
  csv << data_for_report
end
Sisneros answered 23/1, 2013 at 21:47 Comment(3)
It is one step closer.. Thank you!Briannebriano
Note that it's Tempfile, not TempFile.Vend
The link to Ruby doc is brokenGrivet
H
5
temp_file = CSV.generate do |csv|
  csv << data_for_report
end

Reports.sendreport users temp_file
Hallee answered 4/9, 2019 at 21:10 Comment(1)
This is the correct answer to the question Is there anyway to write the following code in Ruby without writing the file to disk? Other answers seems to be workarounds (tempfiles)Penuche
T
3

With your current code that's not possible, if your code would use file pointers/handles instead you can do the following:

require 'csv'
require 'stringio'

data_for_report = [1,2,3,4]
temp_file = StringIO.new # creates a fake file as string.

CSV.new(temp_file, "w") do |csv|
  csv << data_for_report
end

The key problem why it isn't working for your usecase is the line Reports.report users temp_file

If that accepts a handle instead of a string it'll work.

See also this SO: https://mcmap.net/q/537038/-ruby-mock-a-file-with-stringio

Teddy answered 7/1, 2019 at 15:0 Comment(0)
B
2

Try one of the mmap gems. If the library only takes a filename, that's your option.

If it can accept a file-like object, however, you can use a StringIO.

You might consider changing whatever Reports is, making it more general-purpose. It depends on what it's using to create its mail message–this might be trivial.

Brittaneybrittani answered 23/1, 2013 at 21:12 Comment(1)
I will look into StringIO, think that might be what I am looking for... Reports.sendreport is really just my own wrapper on the gmail gem, so I am not really sure if i need a real if or if StringIO will work.Briannebriano
P
0

You can also use CSV.generate:

result = CSV.generate do |csv|
  csv << data_for_report
end

It returns a string

Panaggio answered 18/7, 2024 at 21:34 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.