taglib-ruby and resource balancing (freeing file handles)?

387 views Asked by At

Friends,

I am trying to processing a huge amount of audio files using a Ruby (1.9.3) script by scanning their ID3-Tags using the pretty fast taglib-ruby (0.2.1 via Gem-Server) library.

Here is a part of my code, while audio contains the full file path in a Ruby-String:

begin 
  file_ref = TagLib::FileRef.new(audio) 
  unless file_ref.tag.nil? 
     unless file_ref.tag.artist.nil? or file_ref.tag.title.nil?
       …
     end
  end
ensure
 file_ref = nil
end

Then I get into trouble nearly at the end of the processing. TagLib is complaining about missing read permissions and FileUtils.mv is not longer able to move file afterwards. This is probably the case, because my script does not free file handles TagLib is eating while processing.

Unfortunalty I don not found a certain Ruby method in taglib-ruby API, which eventually call one or better both of TagLibs C-functions:

taglib_tag_free_strings();
taglib_file_free(file);

libmagic Ruby bindings for instance provide a close-Method within its Magic class, so that freeing whithin ensure blocks will work.

Am I just missing the correct Ruby method for taglib-ruby or is it missing at the moment? Is there another way of freeing file handles acquired via Ruby?

1

There are 1 answers

0
robinst On BEST ANSWER

I'm assuming you are in fact using taglib-ruby, not the old ruby-taglib. If you're using taglib-ruby, FileRef (and other ::File classes) have an explicit close method since version 0.3.0, see API documentation.

Update: Since 0.4.0, an even better solution is to use the open class method, which takes a block and handles the closing automatically for you after the block is run. See documentation of open. An example:

TagLib::FileRef.open(file_name) do |file|
  tag = file.tag
  # do things with tag
end