ruby: Can't create new file - ruby

I have a command line program that asks the user a set of questions and stores them in a file. The only problem is, I need it to create a new file and it won't.
Here is what I have tried:
File.open("path/to/file", "w")and File.open("path/to/file", "w+")
Both times I get this error
in 'initialize': No such file or directory # rb_sysopen - path/to/file (Errno::ENOENT)
Here is my current code:
File.open("path/to/file", "w") { |f| f.write(array.join("\n")) }

When someone writes path/to/file in a blog post or documentation, they don't intend for you to literally write path/to/file in your code. The point is that you need to edit that string to actually have the real path to your file, either as a relative path or an absolute path.
You said you are getting this error from the Ruby interpreter:
No such file or directory # rb_sysopen - path/to/file (Errno::ENOENT)
This means that in the current working directory, there is no directory named "path", or if there is a directory named "path", then it doesn't have a child directory named "to".
You could solve the immediate problem by running mkdir -p path/to, but that would be weird. It is better to just write an appropriate path in your code, pointing to a directory that already exists. Try changing the path to simply be output.txt (without any slashes) and see how that works.

Ensure you are using an absolute path, and if so, make sure the directory you want to store the file in is missing. Try creating it first:
require 'fileutils'
FileUtils.mkdir_p '/path/to'
File.open('/path/to/file', 'w') { ... }

Related

How to get filepath to file in another folder unix?

I am trying to write some data in one Ruby file to a file in another folder but I am having trouble identifying the path to get to the file I want to write to.
My current code is:
File.write('../csv_fixtures/loans.csv', 'test worked!')
And my folder structure is as follows:
Where I am trying to run my code in 'run_spec.rb' and write to 'loans.csv'.
Additionally, this is the error I am getting:
Give the path relative to the working directory, not the file that you call File.write from. The working directory is the place you've navigated to through cd before calling the ruby code. If you ran rspec from the root of your project, then the working directory will also be the root. So, in this case, it looks like it would be ./spec/csv_fixtures/loans.csv. You can run puts Dir.pwd to see the working directory that all paths should be relative to.
If you wanted to something more like require_relative, you have to use some sort of workaround to turn it into an absolute path, such as File.dirname(__FILE__) which gives the absolute path of the folder containing the current file:
path = File.join(File.dirname(__FILE__, "../csv_fixtures/loans.csv"))

How can I create a file on my desktop from a Ruby script?

I'm building a webcrawler and I want it to output to a new file that is timestamped. I've completed what I thought would be the more difficult part but I cannot seem to get it to save to the desktop.
Dir.chdir "~/Desktop"
dirname = "scraper_out"
filename = "#{time}"
Dir.mkdir(dirname) unless File.exists?(dirname)
Dir.chdir(dirname)
File.new(filename, "w")
It errors out on the first line
`chdir': No such file or directory # dir_chdir - ~/Desktop
I've read the documentation on FileUtils, File and cannot seem to find where people change into nested directories from the root.
Edit: I don't think FileUtils understands the ~.
~/ is not recognized by Ruby in this context.
Try:
Dir.chdir ENV['HOME']+"/Desktop"
This might help you
Create a file in a specified directory

How can I specify the file location to write and read from in Ruby?

So, I have a function that creates an object specifying user data. Then, using the Ruby YAML gem and some code, I put the object to a YAML file and save it. This saves the YAML file to the location where the Ruby script was run from. How can I tell it to save to a certain file directory? (A simplified version of) my code is this
print "Please tell me your name: "
$name=gets.chomp
$name.capitalize!
print "Please type in a four-digit PIN number: "
$pin=gets.chomp
I also have a function that enforces that the pin be a four-digit integer, but that is not important.
Then, I add this to an object
new_user=Hash.new (false)
new_user["name"]=$name
new_user["pin"]=$pin
and then add it to a YAML file and save it. If the YAML file doesn't exist, one is created. It creates it in the same file directory as the script is run in. Is there a way to change the save location?
The script fo save the object to a YAML file is this.
def put_to_yaml (new_user)
File.write("#{new_user["name"]}.yaml", new_user.to_yaml)
end
put_to_yaml(new_user)
Ultimately, the question is this: How can I change the save location of the file? And when I load it again, how can i tell it where to get the file from?
Thanks for any help
Currently when you use File.write it takes your current working directory, and appends the file name to that location. Try:
puts Dir.pwd # Will print the location you ran ruby script from.
You can specify the absolute path if you want to write it in a specific location everytime:
File.write("/home/chameleon/different_location/#{new_user["name"]}.yaml")
Or you can specify a relative path to your current working directory:
# write one level above your current working directory
File.write("../#{new_user["name"]}.yaml", new_user.to_yaml)
You can also specify relative to your current executing ruby file:
file_path = File.expand_path(File.dirname(__FILE__))
absolute_path = File.join(file_path, file_name)
File.write(absolute_path, new_user.to_yaml)
You are supplying a partial pathname (a mere file name), so we read and write from the current directory. Thus you have two choices:
Supply a full absolute pathname (personally, I like to use the Pathname class for this); or
Change the current directory first (with Dir.chdir)

Open file from same directory

Ok so with siriproxy it my lib folder along with the rb file for the plugin I have created a myconfig.yml file so I can change certain settings by writing to that file.
I have been able to write to the file but only if I include the full path all the way from the home directory down.
But is there not a way to open the file from the same directory i am in? I have tried every path combination I can think of.
There has to be one i am missing
If you use the following in your ruby file, you should get the absolute path where it is
File.expand_path(__FILE__)
From doc __FILE__
The name of the file currently being executed, including path relative to the directory where the application was started up (or the current directory, if it has been changed)
From doc File.expand_path
Converts a pathname to an absolute pathname.
As you probably want the directory, you should use File.dirname(__FILE__), so the path of your file myconfig.yml should be obtained with
File.join(File.expand_path(File.dirname(__FILE__)), 'myconfig.yml')
In more recent Ruby (>=2.0.0), you can use __dir__ (from Archonic's comment):
Returns the canonicalized absolute path of the directory of the file from which this method is called. It means symlinks in the path is resolved. If FILE is nil, it returns nil. The return value equals to File.dirname(File.realpath(FILE)).

How do I read from a file in the same directory?

I'm very much a beginner. I'd like to learn to read and write a file. Here's what I'm trying.
rdfile = File.open('bhaarat.txt', 'r+')
Unfortunately, this is returning "C:/directoriesblahblah/ubuntu3.rb:1:in 'initialize': No such file or directory - bhaarat.txt (Errno::ENOENT)
I have found solutions but I am not only new to Ruby but new to programming in general so I couldn't get an answer that made sense to me out of those.
Thanks in advance!
To obtain the path to the current file, you can use:
__FILE__
To obtain the directory in which the current file exists, you can use:
File.dirname(__FILE__)
To create a path from strings, you can use:
File.join('part1', 'part2', ...)
Therefore, to create a path to a file in that directory, you can use:
File.join(File.dirname(__FILE__), 'filename')
If your file name is bhaarat.txt, the above becomes:
File.join(File.dirname(__FILE__), 'bhaarat.txt')
If you replace that in your code, you will get:
rdfile = File.open(File.join(File.dirname(__FILE__), 'bhaarat.txt'), 'r+')
You can also make this a separate variable, if you want, to make the code more readable:
path = File.join(File.dirname(__FILE__), 'bhaarat.txt')
rdfile = File.open(path, 'r+')
The file is searched in the current directory, not the directory where the script is located.
C:\> ruby scripts\ubuntu3.rb
No such file or directory - bhaarat.txt
Move to the file location first and then run the script. For example, if the file is located in the same directory with the script:
C:\> cd scripts
C:\scripts> ruby ubuntu3.rb
File.read(File.join(__dir__, 'filename'))
Found something that did the trick. Searched a little harder and found this:
I changed my original code
rdfile = File.open('bhaarat.txt', 'r+')
to
rdfile = File.open(File.join(File.dirname(__FILE__),'bhaarat.txt'), 'r+')
and that makes it look in the directory of your .rb file, instead of the directory that your command prompt is currently in.

Resources