在Sinatra中读取本地文件时出错

时间:2012-10-26 00:27:39

标签: ruby sinatra

我正在尝试编写一个从文件中读取列表的Sinatra应用程序,然后从该列表中回吐一个随机项。

但是,我无法弄清楚要读取文件的路径。当我尝试在浏览器中加载项目时,Sinatra说“没有这样的文件或目录”:

Errno::ENOENT at /wod
No such file or directory - http://localhost:4567/listing.txt

以下是代码:

require 'sinatra'

@list

get /item
  puts read_list[rand(@list.size)]
end

def read_list
  File.open('listing.txt', 'r').readlines
end

我有/public中的文件,Sinatra README说这是托管静态文件的默认位置。此外,如果我将其放入/public,我可以导航到localhost:4567/listing.txt并在浏览器中读取该文件。

2 个答案:

答案 0 :(得分:3)

我注意到了几件事:

get /item

不正确,应该是:

get '/item' do

如果你在Ruby代码所在的同一目录中启动代码,那么当前的工作目录将是".",这是Ruby在尝试时所看到的:

File.open('listing.txt', 'r').readlines

Ruby实际上会使用'./listing.txt'作为路径。如果您从应用程序的根目录手动启动代码,那就没关系,但是如果您尝试从其他任何地方启动代码,那么这样做效果不佳。

当您实际尝试加载用于Web服务器的内容时​​,最好明确说明文件的位置。您可以做一些事情来帮助使其更具防弹性,而不是依靠机会。考虑一下:

def read_list
  running_dir = File.dirname(__FILE__)
  running_dir = Dir.pwd if (running_dir == '.')
  File.open(running_dir + '/public/listing.txt', 'r').readlines
end

File.dirname__FILE__获取路径信息,这是当前运行文件的绝对路径和名称。如果应用程序是从与文件相同的目录启动的,那将是.,这不是我们想要的。在这种情况下,我们需要当前工作目录的绝对路径,Dir.pwd返回。然后我们可以从应用程序的根目录将其附加到所需文件的路径。

答案 1 :(得分:2)

您需要File.read('public/listing.txt', 'r')来获取您想要的内容。

File.open不是Sinatra的一部分,并且不知道在静态文件的特定位置查找,所以它只是在当前工作目录中查找。