Storing data to GridFS from a Java client

In the previous recipe, we saw how to store data to GridFS using the command-line utility called mongofiles, which comes with MongoDB to manage large data files. To get an idea of what GridFS is and what collections are used behind the scenes to store the data, refer to the previous recipe. In this recipe, we will look at storing data to GridFS using a Java client. The program will be a highly scaled down version of the mongofiles utility and focuses only on how to store, retrieve, and delete data rather than trying to provide a lot of options such as mongofiles do.

Getting ready

Refer to the Connecting to a single node from a Java client recipe from Chapter 1, Installing and Starting the MongoDB Server, for all the necessary setup for this recipe. If you are interested in more details on Java drivers, refer to the following recipes in Chapter 3, Programming Language Drivers:

  • Executing query and insert operations using a Java client
  • Executing update and delete operations using a Java client
  • Aggregation in Mongo using a Java client
  • MapReduce in Mongo using a Java client

Open a Mongo shell and connect to the local mongod instance listening to port 27017. For this recipe, we will be using the project mongo-cookbook-gridfs. This project is available in the source code bundle downloadable from the book's website. The folder needs to be extracted on the local filesystem. Open a terminal on your operating system and go to the root of the project extracted. It should be the directory where the pom.xml file is found. Also, save the glimpse_of_universe-wide.jpg file on the local filesystem, just as in the previous recipe. This file can be found in the downloadable code bundle from the book's website.

How to do it…

  1. We are assuming that the collections of GridFS are clean and no prior data is uploaded. If there is nothing crucial in the database, you may execute the following queries to clear the collection. Do exercise caution before dropping the collections though:
    > use test
    > db.fs.chunks.drop()
    > db.fs.files.drop()
    
  2. Open an operating system shell and execute the following command:
    $ mvn clean compile exec:java -Dexec.mainClass=com.packtpub.mongo.cookbook.GridFSTests -Dexec.args="put ~/glimpse_of_universe-wide.jpg universe.jpg"
    

    Note

    The file I need to upload was placed in the Home directory. You may choose to give the filepath of the image file after the put command. Note that if the path contains spaces, the whole path needs to be within single quotes.

  3. If the preceding command runs successfully, you should see the following output:
    Successfully written to universe.jpg, details are:
    Upload Identifier: 5314c05e1c52e2f520201698
    Length: 2711259
    MD5 hash: d894ec31b8c5addd0c02060971ea05ca
    Chunk Side in bytes: 262144
    Total Number Of Chunks: 11
    
  4. Once the preceding execution is successful, which we can confirm from the console output, execute the following queries from the Mongo shell:
    > db.fs.files.findOne({filename:'universe.jpg'})
    > db.fs.chunks.find({}, {data:0})
    
  5. Now we will get the file from GridFS to the local filesystem. Execute the following command to perform this operation. Ensure that the directory to which we are writing, the second parameter after the get operation, is writable to the user.
    $ mvn clean compile exec:java -Dexec.mainClass=com.packtpub.mongo.cookbook.GridFSTests -Dexec.args="get '~/universe.jpg' universe.jpg"
    
  6. Confirm that the file is present on the local filesystem at the mentioned location. We should see the following output on the console output to indicate a successful write operation:
    Connected successfully..
    Successfully written 2711259 bytes to ~/universe.jpg
    
  7. Finally, we will delete the file from GridFS as follows:
    $ mvn clean compile exec:java -Dexec.mainClass=com.packtpub.mongo.cookbook.GridFSTests -Dexec.args="delete universe.jpg"
    
  8. On successful deletion, we should see the following output on the console:
    Connected successfully..
    Removed file with name 'universe.jpg' from GridFS
    

How it works…

The com.packtpub.mongo.cookbook.GridFSTests class accepts three types of operations, put, get, and delete, to upload a file to GridFS, get contents from GridFS to a local filesystem, and delete files from GridFS respectively.

The class accepts up to three parameters. The first one is the operation with valid values as get, put, and delete. The second parameter is relevant for the get and put operations and is the name of the file on the local filesystem to write the downloaded content to, or from which the content is sourced for upload. The third parameter is the name of the file in GridFS, which is not necessarily the same as the name on the local filesystem. However, for delete, only the filename on GridFS is needed for deletion purposes.

Let us see some important snippets of code from the class that is specific to GridFS.

Open the com.packtpub.mongo.cookbook.GridFSTests class in your favorite IDE and look for the handlePut, handleGet, and handleDelete methods. These are the methods where all the logic is. First, we will start with the handlePut method, which is meant to upload the contents of the file from the local filesystem to GridFS.

Irrespective of which operation we do, we will create an instance of the com.mongodb.gridfs.GridFS class. In our case, we instantiated it as follows:

GridFS gfs = new GridFS(client.getDB("test"));

The constructor of this class takes the database instance of the com.mongodb.DB class in which we wish to create the GridFS tables fs.chunks and fs.files, which will store the uploaded content. Once the instance of GridFS is created, we will invoke the createFile method on it. This method accepts two parameters; the first one is InputStream, which sources the bytes of the content to be uploaded, and the second parameter is the name of the file that will be saved on GridFS. However, this method doesn't create the file on GridFS but returns an instance of com.mongodb.gridfs.GridFSInputFile. The upload will happen only when we call the save method in this returned object. There are a few overloaded variants of this createFile method. For more details, refer to the Javadoc of the com.mongodb.gridfs.GridFS class.

Our next method is handleGet, which gets the contents of the file saved on GridFS to a local filesystem. Similar to the com.mongodb.DBCollection class, the class com.mongodb.gridfs.GridFS has the find and findOne methods to search. However, instead of accepting any DBObject query, find and findOne in GridFS accept the filename or the ObjectId value of the document to search in the fs.files collection. Similarly, the return value is not a DBCursor but an instance of com.mongodb.gridfs.GridFSDBFile. This class has various methods that let us get the InputStream of the bytes of the file present on GridFS. Other methods are writeTo, which writes to the given file or OutputStream and a getLength method that give the number of bytes in the file. For details, refer to the Javadoc of the com.mongodb.gridfs.GridFSDBFile class.

Finally, we look at the handleDelete method that is used to delete the files on GridFS and is the simplest of the lot. The method on the object of GridFS is remove, which accepts a string argument that is the name of the file to delete on the server. The return type of this method is void. So, irrespective of whether the content is present on GridFS or not, the method will not return a value nor throw an exception if a name is provided to this method for a file that doesn't exist.

See also

  • The Storing binary data in MongoDB recipe
  • The Storing data to GridFS from a Python client recipe
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset