32

I want to write something to a file.

# where userid is any intger [sic]
path = Rails.root + "public/system/users/#{user.id}/style/img.jpg" 
File.open(path, 'wb') do |file|
  file.puts f.read
end 

When this code is executed, I'm getting this error. I know this folder doesn't exist, but File.open with w mode creates a new file if it doesn't exist.

Why is this not working?

Promise Preston
  • 24,334
  • 12
  • 145
  • 143
ashwintastic
  • 2,262
  • 3
  • 22
  • 49

7 Answers7

61

Trying to use gets inside a rake task? You may be seeing this error message:

Errno::ENOENT: No such file or directory @ rb_sysopen

Did you try searching the error, and end up on this page? This answer is not for the OP, but for you.

Use STDIN.gets. Problem solved. That's because just using gets resolves back to $stdin.gets and rake is overriding the global variable so that gets tries to open a file handle that doesn't exist. Here's why:

What's the difference between gets.chomp() vs. STDIN.gets.chomp()?

Community
  • 1
  • 1
Day Davis Waterbury
  • 2,052
  • 18
  • 31
38

File.open(..., 'w') creates a file if it does not exist. Nobody promised it will create a directory tree for it.

Another thing, one should use File#join to build directory path, rather than dumb string concatenation.

path = File.join Rails.root, 'public', 'system', 'users', user.id.to_s, 'style'

FileUtils.mkdir_p(path) unless File.exist?(path) 
File.open(File.join(path, 'img.jpg'), 'wb') do |file|
  file.puts f.read
end
ashwintastic
  • 2,262
  • 3
  • 22
  • 49
Aleksei Matiushkin
  • 119,336
  • 10
  • 100
  • 160
  • Just being curious: Why is is File.join advisable here? It joins the path components always with the platform specific separator (for instance, `\` on Windows). While there **are** cases, where this is what we want to achive, we usually try to stick with `/` on all platforms, because this gives less headache with respect of portability. In the case of the code posted here, I don't see why platform-specific file separators could be an advantage. – user1934428 Apr 01 '16 at 08:22
  • 1
    @user1934428 “we usually try to stick with / on all platforms, because this gives less headache with respect of portability”—besides this is nonsense, using `File.join` helps to avoid silly mistakes like the one in the OP: `Rails.root` does not end with a slash and using `+` gives `/railsrootpublic/` (note the slash miss above.) – Aleksei Matiushkin Apr 01 '16 at 08:26
  • @mudasobwa: In my rails console Rails.root + "bla/bla" GIves correct path :) – ashwintastic Apr 01 '16 at 09:20
  • 1
    @mudasobwa : it worked but I have to make some changes like Dir.mkdir only create directory not a directory tree, I used FileUtils.mkdir_p : thnk for the help – ashwintastic Apr 04 '16 at 06:56
0

You'll also get this error when File.open(..., 'w') was unable to open the file i.e. because of protected folder access under Windows 10.

henon
  • 2,022
  • 21
  • 23
0

I had this issue when trying to create a file in Ruby.

I was trying to use the command below to create a new file:

File.new("testfile", "r")

and

File.open("testfile", "r")

but then I was getting the error below:

(irb):1:in `initialize': No such file or directory @ rb_sysopen - testfile (Errno::ENOENT)

Here's how I fixed it:

The issue was that I did not specify the right mode for the file. The format for creating new files is:

File.new(filename, mode)

OR

File.open(filename, mode)

And the various modes are:

"r"  Read-only, starts at beginning of file  (default mode).

"r+" Read-write, starts at beginning of file.

"w"  Write-only, truncates existing file
     to zero length or creates a new file for writing.

"w+" Read-write, truncates existing file to zero length
     or creates a new file for reading and writing.

"a"  Write-only, each write call appends data at end of file.
     Creates a new file for writing if file does not exist.

"a+" Read-write, each write call appends data at end of file.
     Creates a new file for reading and writing if file does
     not exist.

However, my command File.new("testfile", "r") was using the "r" Read-only mode which was trying to read from an existing file called testfile instead of creating a new one. All I had to do was to modify the command to use the "w" Write-only mode:

File.new("testfile", "w")

OR

File.open("testfile", "w")

Reference: File in Ruby

halfer
  • 19,824
  • 17
  • 99
  • 186
Promise Preston
  • 24,334
  • 12
  • 145
  • 143
0

In my case is was because in method above I had:

Dir.chdir(some_folder)

so it changes current directory for next File.open or File.readlines calls.

Yvgen
  • 2,036
  • 2
  • 23
  • 27
0

I had the same error and had to replace open() with URI.open().

Minimal reproducible example

This gives the error

require 'open-uri'
require 'nokogiri'

url = "https://www.example.com"
html_file = open(url)
# Errno::ENOENT: No such file or directory @ rb_sysopen - https://www.example.com

..but after you replace open() with URI.open() there's no error:

require 'open-uri'
require 'nokogiri'

# Open the URL
url = "https://www.example.com"
html_file = URI.open(url)
stevec
  • 41,291
  • 27
  • 223
  • 311
-1

please use

bundle exec jekyll serve --disable-disk-cache

or

bundle exec jekyll bui --disable-disk-cache
HatLess
  • 10,622
  • 5
  • 14
  • 32