Envision, Create, Share

Welcome to HBGames, a leading amateur game development forum and Discord server. All are welcome, and amongst our ranks you will find experts in their field from all aspects of video game design and development.

[Resolved] "Too many open files" error for File class</span>

Status
Not open for further replies.
I encountered another new-to-me error message, so let's fire it first:
Errno::EMFILE occurred.

Too many open files - Language/English/Generic.txt
Well, it occured after I inserted my Multiple Language Script in a new project to work on it... strangely, this is the first time this error occurred, without myself changed something at the script at all... I tried several things including File.close (which should be redundant, as File.open closes the file at the end of the block according to my knowledge, but apparently... not XD ), but nothing worked...

Here's the method, 'id' being 'English' (string) and line 12 marked with red...
Code:
  def read_text(id)
    [COLOR=Red]file = File.open("Language/" + @language + "/Generic.txt")[/COLOR]
    content = file.readlines
    for line in 0..content.size-1
      if content[line].include?("*" + id)
        temp_content = content[line]
        temp_content.gsub!(("*" + id + " "), $game_system.read_text("000"))
      end
    end
    return temp_content
  end
I hope someone can help me with this...
 
close is an instance-method of the IO-class (which is the superclass of File). IO-ports are closed when they are garbage-collected, but relying on that is somehow dirty behavior.

Try
Code:
file.close
after you read the content of the file.
 
This returns a "stack level too deep" error for this line:
Code:
if content[line].include?("*" + id)
I placed the file.close directly above that line, by the way... if I place it below the branch, it returns the first error...
 
Shame on you BlueScope. Using a Foreach, and using one improperly! Never have an inclusive range with the end point minus one. That's what the exclusive range is for. And for this bit of code, you should use an each iteration.

Now try using this code:
Code:
  def read_text(id)
    file = File.open("Language/#{@language}/Generic.txt")
    content = file.readlines
    content.each do |line|
      if line ~= "*#{id} "
        line.sub!("*#{id} ", $game_system.read_text('000'))
      end
    end
    file.close
    return line
  end
 
or you can try this

Code:
  def read_text(id)
    filename = "Language/" + @language + "/Generic.txt"
    content = IO.readlines(filename);
    content.each do |line|
      if line ~= "*#{id} "
        line.sub!("*#{id} ", $game_system.read_text('000'))
      end
    end
    return content
  end
@yeyinde, line is not a local variable, it scope is limited to the each loop. so you should have returned content since you are passing each line by reference within the loop.
 
You're both wrong, as 'id' isn't an integer you can check for, it's a string (as stated in my first post :P ), therefore, it returns a syntax error for the 'if line -= ...' line.

@Yeyinde: '...' is inclusive, '..' is exclusive, right? Meaning I didn't even use an inclusive range... Well, the reason why I used both '..' and '-1' was because I had problems reading the file without the '-1' for whatever reason... won't read the file properly. Anyway, you might look at an example of how my file looks like:

*00000 Author
*00001 BlueScope
*00002 Language Version
*00003 1.0
*00004 Game Version
For example, '*00001' is passed to the method as the variable 'id', while 'Author' has to be returned by the method. Simple stuff... and it worked before...
 
Try this:
Code:
  def read_text(id)
    File.open("Language/" + @language + "/Generic.txt") {|file|
      content = file.readlines
      for line in 0...content.size
        if content[line].include?("*" + id)
          temp_content = content[line]
          temp_content.gsub!(("*" + id + " "), "")
        end
      end
    }
    return temp_content
  end
The open function plus a block autocloses the file after the block ends, this can make the game quicker.
The problem is: "$game_system.read_text("000")", that makes a circular function, so the function recall it self all the time, but only if this read_text method is from the Game_System class. With a "", the gsub function will remove the id.
 
Try this:
Code:
  def read_text(id)
    File.open("Language/" + @language + "/Generic.txt") {|file|
      content = file.readlines
      for line in 0...content.size
        if content[line].include?("*" + id)
          temp_content = content[line]
          temp_content.gsub!(("*" + id + " "), "")
        end
      end
      return "???" if temp_content.nil?
      return temp_content
    }
  end
 
Status
Not open for further replies.

Thank you for viewing

HBGames is a leading amateur video game development forum and Discord server open to all ability levels. Feel free to have a nosey around!

Discord

Join our growing and active Discord server to discuss all aspects of game making in a relaxed environment. Join Us

Content

  • Our Games
  • Games in Development
  • Emoji by Twemoji.
    Top