stings
stings

Reputation: 3

Why doesn't File.exist find this file?

I have a variable like book_file_name which stores a filename with path like this:

 book_file_name
=> "./download/Access\\ Database\\ Design\\ \\&\\ Programming,\\ 3rd\\ Edition.PDF"

puts book_file_name
./download/Access\ Database\ Design\ \&\ Programming,\ 3rd\ Edition.PDF
=> nil

book_file_name.length
=> 71

When I use File.exists? to check the file, something is wrong.

This is how I use the string:

File.exists?("./download/Access\ Database\ Design\ \&\ Programming,\ 3rd\ Edition.PDF")
=> true

This is how I use the variable:

File.exists?(book_file_name)
=> false

What's wrong with the variable?

Upvotes: 0

Views: 1106

Answers (2)

SteveTurczyn
SteveTurczyn

Reputation: 36860

The string

 "./download/Access\ Database\ Design\ \&\ Programming,\ 3rd\ Edition.PDF"

is in double-quotes, which causes the backslash+space to be replaced with space

This won't happen with a string variable like book_file_name, and won't happen in a string enclosed within single quotes.

I can see the actual book name with path is

'./download/Access Database Design & Programming, 3rd Edition.PDF'

so

File.exists?('./download/Access Database Design & Programming, 3rd Edition.PDF')
File.exists?("./download/Access Database Design & Programming, 3rd Edition.PDF")
book_file_name = './download/Access Database Design & Programming, 3rd Edition.PDF'
File.exists?(bookfilename)
book_file_name = "./download/Access Database Design & Programming, 3rd Edition.PDF"
File.exists?(bookfilename)

will all work just fine... so you're better off not using backslashes.

Upvotes: 2

Daniel Brady
Daniel Brady

Reputation: 954

As you have shown in your code snippets, the string contained in your variable has backslashes in it. You don't need to escape the spaces, but if you do, you only need to escape them with one backslash. As it stands, you are using double backslashes; the first backslash escapes the second, and has no impact on the space.

puts "file name with spaces"
# => file name with spaces
puts "file\ name\ with\ spaces"
# => file name with spaces
puts "file\\ name\\ with\\ spaces"
# => file\ name\ with\ spaces

This explains why your string literal succeeds where your variable fails: the two strings are not equivalent. So just store the same string literal that succeeded (the one with single backslashes) or else the string literal without any backslashes and you should be good to go.

Upvotes: 0

Related Questions