Class | Mongo::GridIO |
In: |
lib/mongo/gridfs/grid_io_fix.rb
lib/mongo/gridfs/grid_io.rb |
Parent: | Object |
GridIO objects represent files in the GridFS specification. This class manages the reading and writing of file chunks and metadata.
DEFAULT_CHUNK_SIZE | = | 256 * 1024 |
DEFAULT_CONTENT_TYPE | = | 'binary/octet-stream' |
PROTECTED_ATTRS | = | [:files_id, :file_length, :client_md5, :server_md5] |
chunk_size | [R] | |
client_md5 | [R] | |
content_type | [R] | |
file_length | [R] | |
file_position | [R] | |
filename | [R] | |
files_id | [R] | |
metadata | [R] | |
server_md5 | [R] | |
upload_date | [R] |
Create a new GridIO object. Note that most users will not need to use this class directly; the Grid and GridFileSystem classes will instantiate this class
@param [Mongo::Collection] files a collection for storing file metadata. @param [Mongo::Collection] chunks a collection for storing file chunks. @param [String] filename the name of the file to open or write. @param [String] mode ‘r’ or ‘w’ or reading or creating a file.
@option opts [Hash] :query a query selector used when opening the file in ‘r’ mode. @option opts [Hash] :query_opts any query options to be used when opening the file in ‘r’ mode. @option opts [String] :fs_name the file system prefix. @option opts [Integer] (262144) :chunk_size size of file chunks in bytes. @option opts [Hash] :metadata ({}) any additional data to store with the file. @option opts [ObjectId] :_id (ObjectId) a unique id for
the file to be use in lieu of an automatically generated one.
@option opts [String] :content_type (‘binary/octet-stream’) If no content type is specified,
the content type will may be inferred from the filename extension if the mime-types gem can be loaded. Otherwise, the content type 'binary/octet-stream' will be used.
@option opts [Boolean] :safe (false) When safe mode is enabled, the chunks sent to the server
will be validated using an md5 hash. If validation fails, an exception will be raised.
# File lib/mongo/gridfs/grid_io.rb, line 53 def initialize(files, chunks, filename, mode, opts={}) @files = files @chunks = chunks @filename = filename @mode = mode opts = opts.dup @query = opts.delete(:query) || {} @query_opts = opts.delete(:query_opts) || {} @fs_name = opts.delete(:fs_name) || Grid::DEFAULT_FS_NAME @safe = opts.delete(:safe) || false @local_md5 = Digest::MD5.new if @safe @custom_attrs = {} case @mode when 'r' then init_read when 'w' then init_write(opts) else raise GridError, "Invalid file mode #{@mode}. Mode should be 'r' or 'w'." end end
# File lib/mongo/gridfs/grid_io.rb, line 74 def [](key) @custom_attrs[key] || instance_variable_get("@#{key.to_s}") end
# File lib/mongo/gridfs/grid_io.rb, line 78 def []=(key, value) if PROTECTED_ATTRS.include?(key.to_sym) warn "Attempting to overwrite protected value." return nil else @custom_attrs[key] = value end end
Creates or updates the document from the files collection that stores the chunks’ metadata. The file becomes available only after this method has been called.
This method will be invoked automatically when on GridIO#open is passed a block. Otherwise, it must be called manually.
@return [BSON::ObjectId]
# File lib/mongo/gridfs/grid_io.rb, line 232 def close if @mode[0] == ?w if @current_chunk['n'].zero? && @chunk_position.zero? warn "Warning: Storing a file with zero length." end @upload_date = Time.now.utc id = @files.insert(to_mongo_object) end id end
Read a chunk of the data from the file and yield it to the given block.
Note that this method reads from the current file position.
@yield Yields on chunk per iteration as defined by this file‘s
chunk size.
@return [Mongo::GridIO] self
# File lib/mongo/gridfs/grid_io.rb, line 252 def each return read_all unless block_given? while chunk = read(chunk_size) yield chunk break if chunk.empty? end self end
Return a boolean indicating whether the position pointer is at the end of the file.
@return [Boolean]
# File lib/mongo/gridfs/grid_io.rb, line 186 def eof raise GridError, "file not opened for read #{@mode}" unless @mode[0] == ?r @file_position >= @file_length end
This fixes a comparson issue in JRuby 1.9
# File lib/mongo/gridfs/grid_io_fix.rb, line 23 def get_md5 md5_command = BSON::OrderedHash.new md5_command['filemd5'] = @files_id md5_command['root'] = @fs_name @server_md5 = @files.db.command(md5_command)['md5'] if @safe @client_md5 = @local_md5.hexdigest if @local_md5.to_s != @server_md5.to_s raise GridMD5Failure, "File on server failed MD5 check" end else @server_md5 end end
Return the next line from a GridFS file. This probably makes sense only if you‘re storing plain text. This method has a somewhat tricky API, which it inherits from Ruby‘s StringIO#gets.
@param [String, Integer] separator or length. If a separator,
read up to the separator. If a length, read the +length+ number of bytes. If nil, read the entire file.
@param [Integer] length If a separator is provided, then
read until either finding the separator or passing over the +length+ number of bytes.
@return [String]
# File lib/mongo/gridfs/grid_io.rb, line 205 def gets(separator="\n", length=nil) if separator.nil? read_all elsif separator.is_a?(Integer) read_length(separator) elsif separator.length > 1 read_to_string(separator, length) else read_to_character(separator, length) end end
Read the data from the file. If a length if specified, will read from the current file position.
@param [Integer] length
@return [String]
the data in the file
# File lib/mongo/gridfs/grid_io.rb, line 94 def read(length=nil) return '' if @file_length.zero? if length == 0 return '' elsif length.nil? && @file_position.zero? read_all else read_length(length) end end
Rewind the file. This is equivalent to seeking to the zeroth position.
@return [Integer] the position of the file after rewinding (always zero).
# File lib/mongo/gridfs/grid_io.rb, line 177 def rewind raise GridError, "file not opened for read" unless @mode[0] == ?r seek(0) end
Position the file pointer at the provided location.
@param [Integer] pos
the number of bytes to advance the file pointer. this can be a negative number.
@param [Integer] whence
one of IO::SEEK_CUR, IO::SEEK_END, or IO::SEEK_SET
@return [Integer] the new file position
# File lib/mongo/gridfs/grid_io.rb, line 145 def seek(pos, whence=IO::SEEK_SET) raise GridError, "Seek is only allowed in read mode." unless @mode == 'r' target_pos = case whence when IO::SEEK_CUR @file_position + pos when IO::SEEK_END @file_length + pos when IO::SEEK_SET pos end new_chunk_number = (target_pos / @chunk_size).to_i if new_chunk_number != @current_chunk['n'] save_chunk(@current_chunk) if @mode[0] == ?w @current_chunk = get_chunk(new_chunk_number) end @file_position = target_pos @chunk_position = @file_position % @chunk_size @file_position end
The current position of the file.
@return [Integer]
# File lib/mongo/gridfs/grid_io.rb, line 169 def tell @file_position end
Write the given string (binary) data to the file.
@param [String] string
the data to write
@return [Integer]
the number of bytes written.
# File lib/mongo/gridfs/grid_io.rb, line 113 def write(io) raise GridError, "file not opened for write" unless @mode[0] == ?w if io.is_a? String if @safe @local_md5.update(io) end write_string(io) else length = 0 if @safe while(string = io.read(@chunk_size)) @local_md5.update(string) length += write_string(string) end else while(string = io.read(@chunk_size)) length += write_string(string) end end length end end