Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/elixir/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails 我得到了一个错误:在用Ruby编写了很多文件之后,打开的文件太多了_Ruby On Rails_Ruby_Ubuntu - Fatal编程技术网

Ruby on rails 我得到了一个错误:在用Ruby编写了很多文件之后,打开的文件太多了

Ruby on rails 我得到了一个错误:在用Ruby编写了很多文件之后,打开的文件太多了,ruby-on-rails,ruby,ubuntu,Ruby On Rails,Ruby,Ubuntu,我有一个脚本,可以生成16000个html页面,并将其保存在系统中。在1013页之后,我得到了一个错误:打开的文件太多 这是生成文件的Ruby代码 FileUtils.mkdir_p "public/users_directory/#{DEFAULT_COUNTRY_CODE}/#{prefix}" FileUtils.mkdir_p "public/users_directory/#{DEFAULT_COUNTRY_CODE}/#{prefix}/#{n/1000}" html_file =

我有一个脚本,可以生成16000个html页面,并将其保存在系统中。在1013页之后,我得到了一个错误:打开的文件太多

这是生成文件的Ruby代码

FileUtils.mkdir_p "public/users_directory/#{DEFAULT_COUNTRY_CODE}/#{prefix}"
FileUtils.mkdir_p "public/users_directory/#{DEFAULT_COUNTRY_CODE}/#{prefix}/#{n/1000}"

html_file = File.new("public/users_directory/#{DEFAULT_COUNTRY_CODE}/#{prefix}/#{n/1000}/#{n}.html", "w")
html_file.write(html)
html_file.close
如您所见,我关闭了最后一行中的文件

有人知道我做错了什么吗?我有Ubuntu 8.04.4 LTS

非常感谢

编辑:

这就是整个剧本

    def self.fetching_directory_page(n=1, letter = nil)
      id = letter == '' ? "" : "/#{letter.upcase}"
      url = "this is a valid url :)"
      agent = WWW::Mechanize.new
      page = agent.get(url)
      html = page.search('div#my_profile_body').to_html

      prefix = id == '' ? 'all' : letter
      FileUtils.mkdir_p "public/users_directory/#{DEFAULT_COUNTRY_CODE}/#{prefix}"
      FileUtils.mkdir_p "public/users_directory/#{DEFAULT_COUNTRY_CODE}/#{prefix}/#{n/1000}"

      html_file = File.new("public/users_directory/#{DEFAULT_COUNTRY_CODE}/#{prefix}/#{n/1000}/#{n}.html", "w")
      html_file.write(html)
      html_file.close

      puts "+ CREATED #{prefix}/#{n/1000}/#{n}.html" 

      new_url = page.parser.xpath("//a[@class='next_page']")[0]['href'] rescue nil

      if new_url.present?
        self.fetching_directory_page(n+1, letter)
      end
    end
它正在获取my users目录的所有用户,并出于缓存原因保存页面。它总共生成16000个文件

这是ulimit-a的结果

    core file size          (blocks, -c) 0
    data seg size           (kbytes, -d) unlimited
    scheduling priority             (-e) 0
    file size               (blocks, -f) unlimited
    pending signals                 (-i) 24640
    max locked memory       (kbytes, -l) 32
    max memory size         (kbytes, -m) unlimited
    open files                      (-n) 24000
    pipe size            (512 bytes, -p) 8
    POSIX message queues     (bytes, -q) 819200
    real-time priority              (-r) 0
    stack size              (kbytes, -s) 8192
    cpu time               (seconds, -t) unlimited
    max user processes              (-u) 24640
    virtual memory          (kbytes, -v) unlimited
    file locks                      (-x) unlimited
在编辑/etc/security/limits之后,我没有得到太多打开的文件的错误,但它只是被卡住了


lsof-u username返回一个大约600个条目的列表,在执行脚本时它不会更改,我不确定这是否是解决问题的最佳方法,但它可能会有帮助:

试着注释掉一半的代码。如果它仍然存在问题,那么将剩下的一半注释掉。继续这样做,直到问题消失。问题解决后,请尝试取消部分代码的注释。继续这样做,直到问题再次出现。更有可能的是,您刚才未注释的那行代码与bug有关。这种解决问题的方法有时被称为二进制切分


在这种情况下,您可能希望确保每次调用“获取目录”页面的内容都不会在不关闭文件的情况下打开新文件。

我不确定这是否是解决问题的最佳方法,但它可能会有所帮助:

试着注释掉一半的代码。如果它仍然存在问题,那么将剩下的一半注释掉。继续这样做,直到问题消失。问题解决后,请尝试取消部分代码的注释。继续这样做,直到问题再次出现。更有可能的是,您刚才未注释的那行代码与bug有关。这种解决问题的方法有时被称为二进制切分


在这种情况下,您可能需要确保每次调用“抓取目录”页面的操作都不会在不关闭它的情况下打开新文件。

问题似乎出在操作系统中,而不是ruby脚本本身

尝试从前面的SO问题中获得建议:

检查当前用户有权打开多少文件:在终端中运行ulimit-a并检查openfiles-n行。默认值为1024

要解决此问题,必须修改以下文件:/etc/security/limits.conf


问题似乎出在操作系统上,而不是ruby脚本本身

尝试从前面的SO问题中获得建议:

检查当前用户有权打开多少文件:在终端中运行ulimit-a并检查openfiles-n行。默认值为1024

要解决此问题,必须修改以下文件:/etc/security/limits.conf


打开的文件没有导致问题。这是递归方法。我改变了这一点,一切都很顺利。

打开的文件并没有造成问题。这是递归方法。我改变了这一点,效果很好。

这是一个次要问题,但Ruby支持使用File.open块,它将自动关闭打开的文件。将该表单与Ruby一起使用被认为是惯用的,而不是您的操作方式:

html_file = File.new("public/users_directory/#{DEFAULT_COUNTRY_CODE}/#{prefix}/#{n/1000}/#{n}.html", "w")
html_file.write(html)
html_file.close
应该是:

File.open("public/users_directory/#{DEFAULT_COUNTRY_CODE}/#{prefix}/#{n/1000}/#{n}.html", "w") do |html_file|
  html_file.print html
end
对于IO.open,从中继承文件.open:

没有关联的块,IO.open是::new的同义词。如果给出了可选代码块,它将作为参数传递给io,并且当该块终止时,io对象将自动关闭。在本例中,::open返回块的值


这是一个次要问题,但Ruby支持使用File.open的块,该块将自动关闭打开的文件。将该表单与Ruby一起使用被认为是惯用的,而不是您的操作方式:

html_file = File.new("public/users_directory/#{DEFAULT_COUNTRY_CODE}/#{prefix}/#{n/1000}/#{n}.html", "w")
html_file.write(html)
html_file.close
应该是:

File.open("public/users_directory/#{DEFAULT_COUNTRY_CODE}/#{prefix}/#{n/1000}/#{n}.html", "w") do |html_file|
  html_file.print html
end
对于IO.open,从中继承文件.open:

没有关联的块,IO.open是::new的同义词。如果给出了可选代码块,它将作为参数传递给io,并且当该块终止时,io对象将自动关闭。在本例中,::open返回块的值


你的剧本里肯定还有别的东西。我已经在OSX上测试了ruby 1.8.7/1.9.2,在Linux上测试了2.6.30内核,即使GC关闭文件的速度也比我在运行lsof时打开文件的速度快。你可以粘贴这个命令的输出,在终端运行它吗?你确定这是所有重要的代码吗?我试着用你提供的代码创建了很多文件,它运行起来没有问题。在这个程序运行时使用lsof查找哪些文件句柄是打开的。只需在创建一个文件后休眠,这样您就有时间运行lsof。lsof-c ruby或lsof-p..@Rishav'ulimit'让我从终端获得无限的权限您的脚本中一定还有其他内容。我在OSX上测试了Ruby1.8.7/1.9.2,在Li上测试了2.6.30内核
nux,在中间运行lsof时,即使GC关闭文件的速度也比我打开文件的速度快。你可以粘贴这个命令的输出,在终端运行它吗?你确定这是所有重要的代码吗?我试着用你提供的代码创建了很多文件,它运行起来没有问题。在这个程序运行时使用lsof查找哪些文件句柄是打开的。只需在创建一个文件后休眠,这样您就有时间运行lsof。lsof-c ruby或lsof-p..@Rishav'ulimit'让我从终端获得无限的支持谢谢你的评论。我尝试了这个,但这不会引起错误,但它只会在同一点卡住…:谢谢你的评论。我尝试了这个,但这不会引起错误,但它只会在同一点卡住…: