Mongodb 是一個開源的no-sql分散式資料庫,Mongodb也為我們提供了基於文件的GFS分散式存儲系統。因此利用Mongodb我們完全可以實現一個分散式的文件存儲以及管理。
下面的內容主要為大家介紹,如何利用java,將大文件存入Mongodb資料庫中。我們這裡所說的大文件,是指大小在16M以上的文件,這也符合MongodbGFS的說明。
首先我們創建一個java工程,這裡我們使用gradle初始化一個java工程,工程結構如下圖。
當然這裡你也可以使用maven來構建一個java工程,對我們後續工作並不會有影響。
接下來我們去mongodb的官網下載其基於java的驅動包。Mongodbjava驅動程序。
這裡我們只需要將這一行,複製到我們工程的build.gradle 文件。
然後刷新gradle,我們可以看到jar包已經添加到我們的程序里。
接下來我們編寫調用的示例,我們新建一個類叫做MongdbGFS.java。然後獲取一個Mongodb的連接,代碼如下:
[java]view plaincopy
packagemongodbGfs;
importcom.mongodb.MongoClient;
importcom.mongodb.client.MongoDatabase;
/**
*
* @author zhaotong
*
*/
publicclassMongodbGFS {
privateMongoClient mongoClient;
//我們進行操作的資料庫
privateMongoDatabase useDatabase;
//初始化
{
mongoClient=newMongoClient("localhost",27017);
useDatabase=mongoClient.getDatabase("zhaotong");
}
}
接下來,我們先不著急寫下面的代碼,我們先找到一個文件放到我們工程裡面,為了我們之後的測試。我在src下面新建了一個文件夾file,裡面存放了一個大約21M的pdf文件。
接下里我們開始進行mongodbGFS文件的存儲。
首先我們講一下mongodbGFS存儲的一個原理。這裡我們引用mongodb官方文檔里的一句話(文檔地址):
GridFS is 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.
When you query a GridFS store for a file, the Java driver will reassemble the chunks as needed.
從上面這段話可以簡單的了解到,mongodb是將文件進行分塊,存儲,當查詢時,mongodb會幫你把你所需要的塊進行組合然後展示給你,因此結合mongodb分散式的特性,我們可以輕易的構建一個分散式的文件存儲。
在利用java驅動存儲時,當我們獲得需要存儲的資料庫連接之後,我們需要先創建一個bucket,官方的說明如下:
Create a GridFS Bucket
GridFS stores files in two collections: a collection stores the file chunks, and a collection stores file metadata. The two collections are in a common bucket and the collection names are prefixed with the bucket name.
通過上面的這段話,我們可以知道,mongodb是將文件分為兩部分存儲,一個是chunks,另一個是files。並且在collection 的名字將會有你bucket的前綴。mongodb支持自定義的bucket的名字,當然也有默認,默認是files。
[java]view plaincopy
*@authorzhaotong
*
*/
publicclassMongodbGFS {
privateMongoClient mongoClient;
//我們進行操作的資料庫
privateMongoDatabase useDatabase;
//bucket
privateGridFSBucket gridFSBucket;
//初始化
{
mongoClient=newMongoClient("localhost",27017);
useDatabase=mongoClient.getDatabase("zhaotong");
// 自定義bucket name
gridFSBucket= GridFSBuckets.create(useDatabase,"zt_files");
// 使用默認的名字
//gridFSBucket=GridFSBuckets.create(useDatabase);
}
}
接下來就是對應的具體操作,代碼如下:
[java]view plaincopy
packagemongodbGfs;
importjava.io.File;
importjava.io.FileInputStream;
importjava.io.FileNotFoundException;
importjava.io.FileOutputStream;
importjava.io.IOException;
importjava.io.InputStream;
importjava.nio.file.Files;
importjava.util.ArrayList;
importjava.util.List;
importorg.bson.Document;
importorg.bson.types.ObjectId;
importcom.mongodb.Block;
importcom.mongodb.MongoClient;
importcom.mongodb.client.MongoDatabase;
importcom.mongodb.client.gridfs.GridFSBucket;
importcom.mongodb.client.gridfs.GridFSBuckets;
importcom.mongodb.client.gridfs.GridFSUploadStream;
importcom.mongodb.client.gridfs.model.GridFSFile;
importcom.mongodb.client.gridfs.model.GridFSUploadOptions;
/**
*
* @author zhaotong
*
*/
publicclassMongodbGFS {
privateMongoClient mongoClient;
// 我們進行操作的資料庫
privateMongoDatabase useDatabase;
// bucket
privateGridFSBucket gridFSBucket;
// 初始化
{
mongoClient =newMongoClient("localhost",27017);
useDatabase = mongoClient.getDatabase("zhaotong");
// 自定義bucket name
gridFSBucket = GridFSBuckets.create(useDatabase,"zt_files");
// 使用默認的名字
// gridFSBucket=GridFSBuckets.create(useDatabase);
}
// 將文件存儲到mongodb,返回存儲完成後的ObjectID
publicObjectId saveFile(String url) {
InputStream ins =null;
ObjectId fileid =null;
// 配置一些參數
GridFSUploadOptions options =null;
// 截取文件名
String filename = url.substring((url.lastIndexOf("/") +1), url.length());
try{
ins =newFileInputStream(newFile(url));
options =newGridFSUploadOptions().chunkSizeBytes(358400).metadata(newDocument("type","presentation"));
// 存儲文件,第一個參數是文件名稱,第二個是輸入流,第三個是參數設置
fileid = gridFSBucket.uploadFromStream(filename, ins, options);
}catch(FileNotFoundException e) {
e.printStackTrace();
}finally{
try{
ins.close();
}catch(IOException e) {
}
}
returnfileid;
}
// 通過OpenUploadStream存儲文件
/**
*
* The GridFSUploadStream buffers data until it reaches the chunkSizeBytes and
* then inserts the chunk into the chunks collection. When the
* GridFSUploadStream is closed, the final chunk is written and the file
* metadata is inserted into the files collection.
*
*/
publicObjectId saveFile2(String url) {
ObjectId fileid =null;
GridFSUploadStream gfsupload =null;
// 配置一些參數
GridFSUploadOptions options =null;
// 截取文件名
String filename = url.substring((url.lastIndexOf("/") +1), url.length());
try{
options =newGridFSUploadOptions().chunkSizeBytes(358400).metadata(newDocument("type","presentation"));
// 存儲文件,第一個參數是文件名稱,第二個是輸入流,第三個是參數設置
gfsupload = gridFSBucket.openUploadStream(filename, options);
byte[] data = Files.readAllBytes(newFile(url).toPath());
gfsupload.write(data);
}catch(FileNotFoundException e) {
e.printStackTrace();
}catch(IOException e) {
e.printStackTrace();
}finally{
gfsupload.close();
fileid = gfsupload.getObjectId();
}
returnfileid;
}
// 查詢所有儲存的文件
publicList findAllFile() {
List filenames =newArrayList();
gridFSBucket.find().forEach(newBlock() {
@Override
publicvoidapply(GridFSFile t) {
filenames.add(t.getFilename());
}
});
returnfilenames;
}
// 刪除文件
publicvoiddeleteFile(ObjectId id) {
gridFSBucket.delete(id);
}
// 重命名文件
publicvoidrename(ObjectId id, String name) {
gridFSBucket.rename(id, name);
}
// 將資料庫中的文件讀出到磁碟上,參數,文件路徑
publicString downFile(String url, ObjectId id) {
FileOutputStream out =null;
String result=null;
try{
out =newFileOutputStream(newFile(url));
gridFSBucket.downloadToStream(id, out);
}catch(FileNotFoundException e) {
e.printStackTrace();
}finally{
try{
out.close();
result=out.toString();
}catch(IOException e) {
e.printStackTrace();
}
}
returnresult;
}
}
對應的單元測試類,大家可以下載運行:
[java]view plaincopy
importorg.bson.types.ObjectId;
importorg.junit.Before;
importorg.junit.Ignore;
importorg.junit.Test;
importmongodbGfs.MongodbGFS;
publicclassMongodbGFSTest {
privateMongodbGFS mgfs;
@Before
publicvoidinit() {
mgfs=newMongodbGFS();
}
// 測試存儲
@Ignore
publicvoidsaveFile() {
ObjectId id=mgfs.saveFile("src/file/2017 Alitech Archive_1.pdf");
System.out.println(id);
}
//測試存儲二
@Ignore
publicvoidsaveFile2() {
ObjectId id=mgfs.saveFile2("src/file/2017 Alitech Archive_1.pdf");
System.out.println(id);
}
// 測試查詢所有在當前資料庫存儲的文件
@Ignore
publicvoidfindAllFile() {
System.out.println(mgfs.findAllFile());
}
// 測試下載文件,存資料庫
@Ignore
publicvoiddownFile() {
System.out.println(mgfs.downFile("src/file/alibaba.pdf",newObjectId("5a6ec218f9afa00c086d94bb")));
}
// 測試刪除文件
@Ignore
publicvoiddeleteFile() {
mgfs.deleteFile(newObjectId("5a6ec218f9afa00c086d94bb"));
}
//測試重命名文件
@Test
publicvoidrename() {
mgfs.rename(newObjectId("5a6ec218f9afa00c086d94bb"),"zhaotong.pdf");
}
}
我們可以在管理工具中看到,我們存儲的文件結構如下:
其每個塊的存儲如下:
喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!
本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧! 請您繼續閱讀更多來自 林志強 的精彩文章: