一、GridFS 簡介
GridFS 是 MongoDB 中用於存儲大文件的一種機制。MongoDB 在設計時就考慮到了處理大文件的問題。當文件大於 16 MB 時,MongoDB 會將文件切分成多個 chunk,每個 chunk 大小為 255kb,然後將每個 chunk 存儲到 GridFS 中。
GridFS 的存儲結構包含兩個部分:文件的元信息(metadata)和 chunk 數據。
二、 GridFS 的元信息
GridFS 使用文件元信息來跟蹤存儲數據的詳細信息。 這些元信息會被存儲在一個名為 “files” 的集合中。下面是 GridFS 中文件元信息的一些字段:
{
"_id" : "filename",
"length" : NumberLong(1024),
"chunkSize" : 261120,
"uploadDate" : ISODate("2018-07-04T03:57:28.942Z"),
"md5" : "1f3870be274f6c49b3e31a0c6728957f",
"filename" : "test.jpg",
"contentType" : "image/jpeg"
}
其中:
- _id:與文件名相同;
- length:整個文件的大小;
- chunkSize:chunk 大小,缺省值為 255KB;
- uploadDate:上傳文件的UTC時間;
- md5:文件的 MD5 碼。在服務端計算時使用此字段可能可靠性較低,推薦一次客戶端計算,上傳到服務端;
- filename:文件名,必須為字符串類型,且長度小於 512 個字節。它是唯一的,還與文件 _id 相關;
- contentType:文件的類型。mime-type 類型使用制定的字符串。在插入和查找時,contentType 字段是可選的。
在文件集合內建立的文檔是,屬性_id是文件名,屬性filename是上傳時的原文件名
三、GridFS 的 chunk 數據
chunk 數據存儲在 GridFS 的另一個集合中,名為 “chunks”。在寫文件時,GridFS 根據指定大小將文件切分成 chunk,然後將每個 chunk 存儲為一個獨立的數據塊。 chunks 集合中存儲 chunk 數據,每個 chunk 對應文件的拆分的分片。
由於 Chunk 是存儲很多的文件,所以 splitsize 最大盡量不要超過256m,如果超過 chunk 就只存儲一份
{
"_id" : ObjectId("5ec04bf97e2f5019757ddd04"),
"files_id" : ObjectId("5eb33e3ed4b3c7231c958a0c"),
"n" : 0,
"data" : BinData(0,"...")
}
其中:
- _id:Chunk 的唯一標識,一般不需要主動定義;
- files_id:與 chunk 相關聯的文件在集合 “files” 中的 id,決定 Chunk 屬於哪個文件;
- n:這個字段是按字節順序編號的,通過這個字段,你就可以還原出原來的文件;
- data:實際數據的二進制表示,是 BinData 類型的值;
- uploadDate:切片上傳的日期;
四、使用 Java 進行 GridFS 操作
1. 引入依賴
在 pom.xml 中添加 mongodb-driver-sync 依賴項。
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongodb-driver-sync</artifactId>
<version>3.11.2</version>
</dependency>
2. 定義 MongoClient 和 GridFSBucket
// 連接 MongoDB 服務
MongoClient mongoClient = MongoClients.create("mongodb://localhost:27017");
GridFSBucket gridFSBucket = GridFSBuckets.create(mongoClient.getDatabase("test"), "fs");
3. 上傳和下載文件
// 上傳文件
try(FileInputStream fileInputStream = new FileInputStream(new File("test.jpg"))) {
ObjectId fileId = gridFSBucket.uploadFromStream("test.jpg", fileInputStream)
System.out.println("上傳成功,文件 ID:" + fileId.toString());
}
// 下載文件
try(FileOutputStream fileOutputStream = new FileOutputStream(new File("test-download.jpg"))) {
gridFSBucket.downloadToStream(fileId, fileOutputStream);
System.out.println("下載完成。");
}
4. 刪除文件
gridFSBucket.delete(fileId);
System.out.println("刪除成功。");
總結
本文詳細介紹了 MongoDB 中的 GridFS 機制,包括 GridFS 的元信息和 chunk 數據結構,以及使用 Java 對 GridFS 進行操作的基本流程。通過深入理解 GridFS,我們可以更好地應對大文件的存儲和管理問題。
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-hant/n/186129.html