All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.mongodb.gridfs.GridFS Maven / Gradle / Ivy

Go to download

The MongoDB Java Driver uber-artifact, containing mongodb-driver, mongodb-driver-core, and bson

There is a newer version: 3.1.0
Show newest version
/*
 * Copyright (c) 2008-2014 MongoDB, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.mongodb.gridfs;

import com.mongodb.BasicDBObject;
import com.mongodb.BasicDBObjectBuilder;
import com.mongodb.DB;
import com.mongodb.DBCollection;
import com.mongodb.DBCursor;
import com.mongodb.DBObject;
import com.mongodb.MongoException;
import org.bson.types.ObjectId;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Logger;

/**
 * 

Implementation of GridFS - a specification for storing and retrieving files that exceed the BSON-document size limit of 16MB.

* *

Instead of storing a file in a single document, GridFS divides a file into parts, or chunks, and stores each of those chunks as a * separate document. By default GridFS limits chunk size to 256k. GridFS uses two collections to store files. One collection stores the * file chunks, and the other stores file metadata.

* *

When you query a GridFS store for a file, the driver or client will reassemble the chunks as needed. You can perform range queries on * files stored through GridFS. You also can access information from arbitrary sections of files, which allows you to "skip" into the middle * of a video or audio file.

* *

GridFS is useful not only for storing files that exceed 16MB but also for storing any files for which you want access without having * to load the entire file into memory. For more information on the indications of GridFS, see MongoDB official documentation.

* * @mongodb.driver.manual core/gridfs/ GridFS */ public class GridFS { private static final Logger LOGGER = Logger.getLogger( "com.mongodb.gridfs" ); /** * File's chunk size */ public static final int DEFAULT_CHUNKSIZE = 255 * 1024; /** * File's max chunk size * * @deprecated You can calculate max chunkSize with a similar formula {@link com.mongodb.MongoClient#getMaxBsonObjectSize()} - 500*1000. * Please ensure that you left enough space for metadata (500kb is enough). */ @Deprecated public static final long MAX_CHUNKSIZE = (long) (3.5 * 1000 * 1000); /** * Bucket to use for the collection namespaces */ public static final String DEFAULT_BUCKET = "fs"; // -------------------------- // ------ constructors ------- // -------------------------- /** * Creates a GridFS instance for the default bucket "fs" in the given database. Set the preferred WriteConcern on the give DB with * DB.setWriteConcern * * @param db database to work with * @throws com.mongodb.MongoException * @see com.mongodb.WriteConcern */ public GridFS(final DB db) { this(db, DEFAULT_BUCKET); } /** * Creates a GridFS instance for the specified bucket in the given database. Set the preferred WriteConcern on the give DB with * DB.setWriteConcern * * @param db database to work with * @param bucket bucket to use in the given database * @throws com.mongodb.MongoException * @see com.mongodb.WriteConcern */ public GridFS(final DB db, final String bucket) { _db = db; _bucketName = bucket; _filesCollection = _db.getCollection( _bucketName + ".files" ); _chunkCollection = _db.getCollection( _bucketName + ".chunks" ); // ensure standard indexes as long as collections are small try { if (_filesCollection.count() < 1000) { _filesCollection.ensureIndex( BasicDBObjectBuilder.start().add( "filename" , 1 ).add( "uploadDate" , 1 ).get() ); } if (_chunkCollection.count() < 1000) { _chunkCollection.ensureIndex( BasicDBObjectBuilder.start().add( "files_id" , 1 ).add( "n" , 1 ).get() , BasicDBObjectBuilder.start().add( "unique" , true ).get() ); } } catch (MongoException e) { LOGGER.info(String.format("Unable to ensure indices on GridFS collections in database %s", db.getName())); } _filesCollection.setObjectClass( GridFSDBFile.class ); } // -------------------------- // ------ utils ------- // -------------------------- /** * Gets the list of files stored in this gridfs, sorted by filename. * * @return cursor of file objects */ public DBCursor getFileList(){ return getFileList(new BasicDBObject()); } /** * Gets a filtered list of files stored in this gridfs, sorted by filename. * * @param query filter to apply * @return cursor of file objects */ public DBCursor getFileList( DBObject query ){ return getFileList(query, new BasicDBObject("filename",1)); } /** * Gets a sorted, filtered list of files stored in this gridfs. * * @param query filter to apply * @param sort sorting to apply * @return cursor of file objects */ public DBCursor getFileList( DBObject query, DBObject sort){ return _filesCollection.find( query ).sort(sort); } // -------------------------- // ------ reading ------- // -------------------------- /** * Finds one file matching the given objectId. Equivalent to findOne(objectId). * * @param objectId the objectId of the file stored on a server * @return a gridfs file * @throws com.mongodb.MongoException */ public GridFSDBFile find(final ObjectId objectId) { return findOne(objectId); } /** * Finds one file matching the given objectId. * * @param objectId the objectId of the file stored on a server * @return a gridfs file * @throws com.mongodb.MongoException */ public GridFSDBFile findOne(final ObjectId objectId) { return findOne( new BasicDBObject( "_id" , objectId ) ); } /** * Finds one file matching the given filename. * * @param filename the name of the file stored on a server * @return the gridfs db file * @throws com.mongodb.MongoException */ public GridFSDBFile findOne(final String filename) { return findOne( new BasicDBObject( "filename" , filename ) ); } /** * Finds one file matching the given query. * * @param query filter to apply * @return a gridfs file * @throws com.mongodb.MongoException */ public GridFSDBFile findOne(final DBObject query) { return _fix( _filesCollection.findOne( query ) ); } /** * Finds a list of files matching the given filename. * * @param filename the filename to look for * @return list of gridfs files * @throws com.mongodb.MongoException */ public List find(final String filename) { return find( filename, null ); } /** * Finds a list of files matching the given filename. * * @param filename the filename to look for * @param sort the fields to sort with * @return list of gridfs files * @throws com.mongodb.MongoException */ public List find(final String filename, final DBObject sort) { return find( new BasicDBObject( "filename" , filename ), sort ); } /** * Finds a list of files matching the given query. * * @param query the filter to apply * @return list of gridfs files * @throws com.mongodb.MongoException */ public List find(final DBObject query) { return find(query, null); } /** * Finds a list of files matching the given query. * * @param query the filter to apply * @param sort the fields to sort with * @return list of gridfs files * @throws com.mongodb.MongoException */ public List find(final DBObject query, final DBObject sort) { List files = new ArrayList(); DBCursor c = null; try { c = _filesCollection.find( query ); if (sort != null) { c.sort(sort); } while ( c.hasNext() ){ files.add( _fix( c.next() ) ); } } finally { if (c != null){ c.close(); } } return files; } /** * @deprecated This method is NOT a part of public API and will be dropped in 3.x versions. */ @Deprecated protected GridFSDBFile _fix( Object o ){ if ( o == null ) return null; if ( ! ( o instanceof GridFSDBFile ) ) throw new RuntimeException( "somehow didn't get a GridFSDBFile" ); GridFSDBFile f = (GridFSDBFile)o; f._fs = this; return f; } // -------------------------- // ------ remove ------- // -------------------------- /** * Removes the file matching the given id. * * @param id the id of the file to be removed * @throws com.mongodb.MongoException */ public void remove(final ObjectId id) { if(id == null) { throw new IllegalArgumentException("file id can not be null"); } _filesCollection.remove( new BasicDBObject( "_id" , id ) ); _chunkCollection.remove( new BasicDBObject( "files_id" , id ) ); } /** * Removes all files matching the given filename. * * @param filename the name of the file to be removed * @throws com.mongodb.MongoException */ public void remove(final String filename) { if(filename == null) { throw new IllegalArgumentException("filename can not be null"); } remove( new BasicDBObject( "filename" , filename ) ); } /** * Removes all files matching the given query. * * @param query filter to apply * @throws com.mongodb.MongoException */ public void remove(final DBObject query) { if(query == null) { throw new IllegalArgumentException("query can not be null"); } for ( GridFSDBFile f : find( query ) ){ f.remove(); } } // -------------------------- // ------ writing ------- // -------------------------- /** * Creates a file entry. After calling this method, you have to call {@link com.mongodb.gridfs.GridFSInputFile#save()}. * * @param data the file's data * @return a gridfs input file */ public GridFSInputFile createFile(final byte[] data) { return createFile( new ByteArrayInputStream( data ), true ); } /** * Creates a file entry. After calling this method, you have to call {@link com.mongodb.gridfs.GridFSInputFile#save()}. * * @param file the file object * @return a GridFS input file * @throws IOException if there are problems reading {@code file} */ public GridFSInputFile createFile(final File file) throws IOException { return createFile(new FileInputStream(file), file.getName(), true); } /** * Creates a file entry. After calling this method, you have to call {@link com.mongodb.gridfs.GridFSInputFile#save()}. * * @param in an inputstream containing the file's data * @return a gridfs input file */ public GridFSInputFile createFile(final InputStream in) { return createFile( in , null ); } /** * Creates a file entry. After calling this method, you have to call {@link com.mongodb.gridfs.GridFSInputFile#save()}. * * @param in an inputstream containing the file's data * @param closeStreamOnPersist indicate the passed in input stream should be closed once the data chunk persisted * @return a gridfs input file */ public GridFSInputFile createFile(final InputStream in, final boolean closeStreamOnPersist) { return createFile( in , null, closeStreamOnPersist ); } /** * Creates a file entry. After calling this method, you have to call {@link com.mongodb.gridfs.GridFSInputFile#save()}. * * @param in an inputstream containing the file's data * @param filename the file name as stored in the db * @return a gridfs input file */ public GridFSInputFile createFile(final InputStream in, final String filename) { return new GridFSInputFile( this , in , filename ); } /** * Creates a file entry. After calling this method, you have to call {@link com.mongodb.gridfs.GridFSInputFile#save()}. * * @param in an inputstream containing the file's data * @param filename the file name as stored in the db * @param closeStreamOnPersist indicate the passed in input stream should be closed once the data chunk persisted * @return a gridfs input file */ public GridFSInputFile createFile(final InputStream in, final String filename, final boolean closeStreamOnPersist) { return new GridFSInputFile( this , in , filename, closeStreamOnPersist ); } /** * Creates a file entry. * * @param filename the file name as stored in the db * @return a gridfs input file * @see GridFS#createFile() */ public GridFSInputFile createFile(final String filename) { return new GridFSInputFile( this , filename ); } /** * This method creates an empty {@link GridFSInputFile} instance. On this instance an {@link java.io.OutputStream} can be obtained using * the {@link GridFSInputFile#getOutputStream()} method. You can still call {@link GridFSInputFile#setContentType(String)} and {@link * GridFSInputFile#setFilename(String)}. The file will be completely written and closed after calling the {@link * java.io.OutputStream#close()} method on the output stream. * * @return GridFS file handle instance. */ public GridFSInputFile createFile() { return new GridFSInputFile( this ); } // -------------------------- // ------ members ------- // -------------------------- /** * Gets the bucket name used in the collection's namespace. Default value is 'fs'. * * @return the name of the file bucket */ public String getBucketName(){ return _bucketName; } /** * Gets the database used. * * @return the database */ public DB getDB(){ return _db; } /** * Gets the {@link DBCollection} in which the file's metadata is stored. * * @return the collection */ protected DBCollection getFilesCollection() { return _filesCollection; } /** * Gets the {@link DBCollection} in which the binary chunks are stored. * * @return the collection */ protected DBCollection getChunksCollection() { return _chunkCollection; } /** * @deprecated Please use {@link #getDB()} for access. */ @Deprecated protected final DB _db; /** * @deprecated Please use {@link #getBucketName()} for access. */ @Deprecated protected final String _bucketName; /** * @deprecated Please use {@link #getFilesCollection()} for access. */ @Deprecated protected final DBCollection _filesCollection; /** * @deprecated Please use {@link #getChunksCollection()} for access. */ @Deprecated protected final DBCollection _chunkCollection; }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy