ร้านค้าระบบไฟล์ที่ออกแบบมาเพื่อป้องกันความขัดแย้งเมื่อใช้กับระบบไฟล์แบบกระจายหรือเครือข่ายพื้นที่จัดเก็บ
โปรด แสดง บน GitHub / NPM และ ดู การอัปเดต
หมายเหตุ: ต้องการ node.js v12 หรือใหม่กว่า
npm install scalable-blob-store --save
const os = require ( 'os' ) ;
const ulid = require ( 'ulid' ) . ulid ; // You need a unique ID generator function
const BlobStore = require ( 'scalable-blob-store' ) ;
const options = {
blobStoreRoot : os . tmpdir ( ) + '/blobs' , // Change this!
idFunction : ulid ,
dirDepth : 4 ,
dirWidth : 1000 ,
} ;
// Creating the blobStore Object
const blobStore = new BlobStore ( options ) ;
const result = await blobStore . createWriteStream ( ) ;
console . dir ( result ) ;
// Logs the result object which contains the blobPath and writeStream.
// Use the writeStream to save your blob.
// Store the blobPath in your database.
//
// result object will be similar to this:
// {
// blobPath: "/01CTZRTWMAD153V20K26S4Y0BW/01CTZRTWMBZW4SPR4E5QGGJYSH/01CTZRTWMB3QXZK04SYFY8ZJVR/01CTZS3KJYFPRQ34S3T15Y798S",
// writeStream: [WriteStream]
// }
//
// In this example the full file path for the blob would be something like this:
// /tmp/blobs/01CTZRTWMAD153V20K26S4Y0BW/01CTZRTWMBZW4SPR4E5QGGJYSH/01CTZRTWMB3QXZK04SYFY8ZJVR/01CTZS3KJYFPRQ34S3T15Y798S
//
// This is based on the blobStoreRoot + blobPath.ดูไฟล์ตัวอย่างเริ่มต้นอย่างรวดเร็วสำหรับรายละเอียดเพิ่มเติม:
หลังจากค้นคว้าการจัดเก็บไฟล์ผู้ใช้หรือที่เก็บข้อมูล Blob สำหรับเว็บแอปพลิเคชันที่ฉันกำลังทำงานอยู่ฉันค้นพบโซลูชันที่ใช้กันทั่วไปที่ใช้โดยนักพัฒนาเว็บคือการจัดเก็บไฟล์โดยใช้ผู้ให้บริการคลาวด์ หลังจากสร้างบัญชีที่มีผู้ให้บริการเช่น Amazon S3, Google Cloud Storage หรือ Azure Storage พวกเขาเพียงแค่เก็บไฟล์แอปพลิเคชันทั้งหมดและ blobs ที่นั่น
ฉันค้นคว้าราคาของการจัดเก็บบนคลาวด์และตัดสินใจว่าฉันต้องการเวอร์ชันท้องถิ่นฟรีที่จะขยายหากจำเป็น
ฉันดูวิธีแก้ปัญหาที่มีอยู่จำนวนมากเช่น FileStorage แต่ไม่พอใจกับความสามารถในการปรับขนาดของโซลูชันเหล่านี้ ส่วนใหญ่ได้รับการออกแบบสำหรับเซิร์ฟเวอร์เดียวและจะทำให้เกิดความขัดแย้งในการเขียนหากระบบไฟล์แบบกระจายระบบไฟล์คลัสเตอร์เช่น Glusterfs หรือเครือข่ายพื้นที่เก็บข้อมูลถูกใช้เป็นระบบไฟล์แบ็กเอนด์
ในการเดินทางด้วยรถยาวฉันกำลังคิดเกี่ยวกับวิธีแก้ปัญหาสำหรับการจัดเก็บหยดของฉันและมาพร้อมกับ scalable-blob-store
เพื่อให้ได้ความสามารถในการปรับขนาดในระบบไฟล์แบบกระจายหรือทำซ้ำ scalable-blob-store ไม่ได้ใช้ไฟล์ดัชนีหรือฐานข้อมูลอื่น ๆ เพื่อจัดการไฟล์บนดิสก์หรือระบบจัดเก็บข้อมูล แต่ระบบไฟล์นั้นถูกใช้เพื่อค้นหาเส้นทางการจัดเก็บข้อมูลล่าสุดตามแอตทริบิวต์ birthtime ของระบบไฟล์ (วันที่สร้างไดเรกทอรี)
เมื่อกำหนดเส้นทางล่าสุดจำนวนไฟล์ภายในไดเรกทอรีจะถูกนับเพื่อให้แน่ใจว่าจะยังคงอยู่ภายใต้ค่าที่กำหนดค่า นี่คือการป้องกันปัญหาประสิทธิภาพของดิสก์เมื่อมีการเก็บไฟล์จำนวนมากภายในไดเรกทอรีเดียว หากจำนวนรายการภายในไดเรกทอรีมีขนาดใหญ่เกินไปจะมีการกำหนดเส้นทางการจัดเก็บใหม่
เนื่องจากไม่มีฐานข้อมูลที่ใช้ในการจัดการไฟล์ในเส้นทางรูทพา ธ จึงขึ้นอยู่กับคุณในการรักษาค่า blobPath ที่ส่งคืนและข้อมูลเมตาเกี่ยวกับไฟล์ที่เก็บไว้ในฐานข้อมูลของคุณเอง
เหตุผลที่ scalable-blob-store สามารถปรับขนาดได้นั้นเกิดจากการตั้งชื่อของไดเรกทอรีและไฟล์ภายในระบบไฟล์ของคุณ ทุกไดเรกทอรีและไฟล์ที่บันทึกไว้ในดิสก์นั้นมีชื่อโดย ID ที่ไม่ซ้ำกันที่สร้างขึ้นตาม Funciton ที่ผู้ใช้กำหนด คุณสามารถใช้เครื่องกำเนิด ID ที่ไม่ซ้ำกันได้เช่น ULID, CUID, UUID V4 หรือ MongoDBS ObjectIds เพื่อชื่อไม่กี่ ตรวจสอบที่เก็บ ID ที่ไม่ซ้ำกันที่ยอดเยี่ยมของฉันสำหรับตัวอย่างเพิ่มเติม การรวมไดเรกทอรีระหว่างเซิร์ฟเวอร์หรือดิสก์ไม่ควรทำให้เกิดการชนกันของชื่อไฟล์
หากระบบไฟล์ที่ทำซ้ำหรือคลัสเตอร์ใช้งานความขัดแย้งเพียงอย่างเดียวที่อาจเกิดขึ้นได้คือเมื่อเซิร์ฟเวอร์หนึ่งกำลังอ่านไฟล์ในขณะที่อีกไฟล์หนึ่งกำลังลบไฟล์เดียวกัน scalable-blob-store ไม่ได้พยายามจัดการความขัดแย้งนี้ แต่จะยกข้อยกเว้น
ด้านล่างนี้เป็นตัวอย่างของโครงสร้างไดเรกทอรีที่สร้างขึ้นโดย scalable-blob-store
ตัวอย่างด้วยไดเรกทอรี CUID และชื่อไฟล์:
b lobs c ij50xia200pzzph3we9r62bi // ← Directory File ↓
b lobs c ij50xia300q1zph3m4df4ypz . . c ij50xiae00qgzph3i0ms0l2wตัวอย่างด้วยไดเรกทอรี UUID และชื่อไฟล์:
b lobs 8 46a291f-9864-40bb-aefe-f29bdc73a761 // ← Directory File ↓
b lobs 8 46a291f-9864-40bb-aefe-f29bdc73a761 . . 8 b86b6fe-6166-424c-aed9-8faf1e62689e scalable-blob-store รองรับตัวเลือกการกำหนดค่าเพื่อให้คุณควบคุมไดเรกทอรีและรหัสไฟล์ที่ใช้ความลึกของโครงสร้างไดเรกทอรีและความกว้างของไดเรกทอรี ตัวเลือกเริ่มต้นให้ไดเรกทอรี 3 รายการที่มี 1,000 รายการที่ให้พื้นที่เก็บข้อมูลทั้งหมดของไฟล์หนึ่งพันล้านภายในโครงสร้างไดเรกทอรี
จุดสนใจอื่น ๆ ที่น่าสนใจ:
dirWidth ไดเรกทอรีถัดไปจะถูกสร้างขึ้นdirWidth ไดเรกทอรีหลักถัดไปจะถูกสร้างขึ้นdirWidth ค่า dirWidth จะถูกละเว้น เขียน
บนแล็ปท็อปของฉันด้วยดิสก์ M.2 SSD การเรียกใช้สคริปต์ Test-FS.JS ให้ผลลัพธ์ต่อไปนี้:
====================================================================================================
Testing scalable-blob-store with the following options:
blobStoreRoot: /tmp/blobs/test-fs
idFunction: ulid
dirDepth: 3
dirWidth: 1000
repeat: 10000
Beginning test...
====================================================================================================
Test complete.
====================================================================================================
{
blobStoreRoot: '/tmp/blobs/test-fs',
dirDepth: 3,
dirWidth: 1000,
runTimeMilliseconds: 83730,
totalDirectories: 12,
totalFiles: 10000,
totalBytes: 430000,
lastBlobPath: '/ckxwcwgwz0001lk9hgq8t9iup/ckxwcwgx00002lk9h6tbpdmq1/ckxwcy36m06yclk9hb0g92dwg/ckxwcy9ip07q4lk9h5uyl10k6'
}
====================================================================================================
Please remove /tmp/blobs/test-fs manually.
====================================================================================================
อ่าน
ประสิทธิภาพการอ่านจะใกล้เคียงกับถ้าไม่เหมือนกันกับความเร็วของดิสก์
วิธีการ blobstore ทั้งหมดภายใน scalable-blob-store ได้กลับสัญญา เหมาะสำหรับการใช้คุณสมบัติภาษา Async/Await
| API | พิมพ์ | ผลตอบแทน |
|---|---|---|
| New Blobstore (ตัวเลือก) | ตัวสร้าง | อินสแตนซ์ Blobstore |
| blobstore.blobstoreroot | อ่านเฉพาะคุณสมบัติ | String |
| blobstore.idfunction | อ่านเฉพาะคุณสมบัติ | Function |
| blobstore.dirdepth | อ่านเฉพาะคุณสมบัติ | Number |
| blobstore.dirwidth | อ่านเฉพาะคุณสมบัติ | Number |
| blobstore.getcurrentblobdir () | วิธี | Promise<String> |
| blobstore.setcurrentblobdir (blobdir) | วิธี | Promise<undefined> |
| blobstore.createwritestream () | วิธี | Promise<Object> |
| blobstore.write (data, writeoptions) | วิธี | Promise<String> |
| blobstore.append (blobpath, ข้อมูล, ภาคผนวก) | วิธี | Promise<undefined> |
| blobstore.copy (blobpath, flags) | วิธี | Promise<String> |
| blobstore.createReadstream (blobpath) | วิธี | Promise<ReadStream> |
| blobstore.read (blobpath, readoptions) | วิธี | Promise<data> |
| blobstore.open (blobpath, ธง, โหมด) | วิธี | Promise<FileHandle> |
| blobstore.realpath (Blobpath, RealPathoptions) | วิธี | Promise<String> |
| blobstore.stat (blobpath) | วิธี | Promise<Stats> |
| blobstore.exists (blobpath) | วิธี | Promise<Boolean> |
| blobstore.remove (blobpath) | วิธี | Promise<undefined> |
new BlobStore(options)ประเภท: ฟังก์ชั่นตัวสร้าง
พารามิเตอร์: options เป็น Object
Returns : วัตถุ BlobStore ใหม่ที่จะใช้ในการจัดเก็บข้อมูล
คำอธิบาย:
คุณสามารถโทรไป new BlobStore(options) หลายครั้งเพื่อสร้างร้านค้า Blob มากกว่าหนึ่งรายการ
ตัวเลือกจะถูกส่งผ่านไปยังฟังก์ชันตัวสร้างเป็น object JavaScript
| สำคัญ | คำอธิบาย | ค่าเริ่มต้น |
|---|---|---|
blobStoreRoot | ไดเรกทอรีรากเพื่อเก็บ blobs | ที่จำเป็น |
idFunction | ฟังก์ชั่น ID ใด ๆ ที่ส่งคืนสตริง ID ที่ไม่ซ้ำกัน | ที่จำเป็น |
dirDepth | คุณต้องการไดเรกทอรีภายใต้รูทลึกแค่ไหน | 3 |
dirWidth | จำนวนไฟล์หรือไดเรกทอรีสูงสุดในไดเรกทอรี | 1,000 |
ตัวอย่าง:
// Start by requiring the `scalable-blob-store` constructor function:
const BlobStore = require ( 'scalable-blob-store' ) ;
// You will need a unique ID function
const uuid = require ( 'uuid' ) ;
// Create the options object
const options = {
blobStoreRoot : '/app/blobs' ,
idFunction : uuid . v4 ,
dirDepth : 4 ,
dirWidth : 2000 ,
} ;
// Create a blob store using the options `object`:
const blobStore = new BlobStore ( options ) ;การสร้างร้านค้า Blob หลายแห่ง:
const userOptions = {
blobStoreRoot : '/app/blobs/user' ,
idFunction : uuid . v4 ,
dirDepth : 4 ,
dirWidth : 2000 ,
} ;
const pdfOptions = {
blobStoreRoot : '/app/blobs/pdf' ,
idFunction : uuid . v4 ,
dirDepth : 2 ,
dirWidth : 300 ,
} ;
const userFileStore = new BlobStore ( userOptions ) ;
const pdfDocumentStore = new BlobStore ( pdfOptions ) ;blobStoreRootประเภท: อ่านเฉพาะคุณสมบัติ
returns: String ที่ตรงกับ options.blobStoreRoot ของคุณค่า blobstoreroot
คำอธิบาย:
นี่เป็นคุณสมบัติที่สะดวกสบายเพื่อให้คุณสามารถส่งวัตถุ Blobstore ไปยังโมดูลย่อยและยังสามารถเข้าถึงคุณสมบัติที่กำหนดค่าได้
ตัวอย่าง:
const BlobStore = require ( 'scalable-blob-store' ) ;
const uuid = require ( 'uuid' ) ;
const options = {
blobStoreRoot : '/app/blobs' ,
idFunction : uuid . v4 ,
dirDepth : 4 ,
dirWidth : 2000 ,
} ;
const blobStore = new BlobStore ( options ) ;
console . log ( blobStore . blobStoreRoot ) ;
// Outputs '/app/blobs' which you configured in the optionsidFunctionประเภท: อ่านเฉพาะคุณสมบัติ
Returns: ฟังก์ชั่น ID ที่ไม่ซ้ำกันที่คุณกำหนดค่าใน options.idFunction ค่า idfunction
คำอธิบาย:
นี่เป็นคุณสมบัติที่สะดวกสบายเพื่อให้คุณสามารถส่งวัตถุ Blobstore ไปยังโมดูลย่อยและยังสามารถเข้าถึงคุณสมบัติที่กำหนดค่าได้
ตัวอย่าง:
const BlobStore = require ( 'scalable-blob-store' ) ;
const uuid = require ( 'uuid' ) ;
const options = {
blobStoreRoot : '/app/blobs' ,
idFunction : uuid . v4 ,
dirDepth : 4 ,
dirWidth : 2000 ,
} ;
const blobStore = new BlobStore ( options ) ;
console . log ( blobStore . idFunction ( ) ) ;
// Outputs 'bac00ab2-5e6d-4b77-bfa4-e9befc3e4279' which is a generated UUID from the idFunction.dirDepthประเภท: อ่านเฉพาะคุณสมบัติ
Returns: Number ที่ตรงกับ options.dirDepth ของคุณค่าความลึก
คำอธิบาย:
นี่เป็นคุณสมบัติที่สะดวกสบายเพื่อให้คุณสามารถส่งวัตถุ Blobstore ไปยังโมดูลย่อยและยังสามารถเข้าถึงคุณสมบัติที่กำหนดค่าได้
ตัวอย่าง:
const BlobStore = require ( 'scalable-blob-store' ) ;
const uuid = require ( 'uuid' ) ;
const options = {
blobStoreRoot : '/app/blobs' ,
idFunction : uuid . v4 ,
dirDepth : 4 ,
dirWidth : 2000 ,
} ;
const blobStore = new BlobStore ( options ) ;
console . log ( blobStore . dirDepth ) ;
// Outputs '4' which you configured in the optionsdirWidthประเภท: อ่านเฉพาะคุณสมบัติ
Returns: Number ที่ตรงกับ options.dirWidth ของคุณค่า dirwidth
คำอธิบาย:
นี่เป็นคุณสมบัติที่สะดวกสบายเพื่อให้คุณสามารถส่งวัตถุ Blobstore ไปยังโมดูลย่อยและยังสามารถเข้าถึงคุณสมบัติที่กำหนดค่าได้
ตัวอย่าง:
const BlobStore = require ( 'scalable-blob-store' ) ;
const uuid = require ( 'uuid' ) ;
const options = {
blobStoreRoot : '/app/blobs' ,
idFunction : uuid . v4 ,
dirDepth : 4 ,
dirWidth : 2000 ,
} ;
const blobStore = new BlobStore ( options ) ;
console . log ( blobStore . dirWidth ) ;
// Outputs '2000' which you configured in the optionsgetCurrentBlobDir()ประเภท: วิธีการ
Returns: Promise ที่แก้ไขเป็น String ที่เป็นไดเรกทอรีการสร้าง Blob ที่ใช้งานอยู่ในปัจจุบัน
คำอธิบาย:
ฟังก์ชั่นนี้ใช้ภายในโดย BlobStore เพื่อกำหนดไดเรกทอรีที่ไฟล์ blob ถัดไปจะถูกบันทึกลงในดิสก์
หากคุณต้องการจัดเก็บไฟล์ blob นอก BlobStore คุณสามารถใช้วิธีนี้เพื่อค้นหาสถานที่ที่เหมาะสมเพื่อวางไฟล์ของคุณ
ตัวอย่าง:
const BlobStore = require ( 'scalable-blob-store' ) ;
const uuid = require ( 'uuid' ) ;
const options = {
blobStoreRoot : '/app/blobs' ,
idFunction : uuid . v4 ,
dirDepth : 3 ,
dirWidth : 2000 ,
} ;
const blobStore = new BlobStore ( options ) ;
async function main ( ) {
try {
console . log ( await blobStore . getCurrentBlobDir ( ) ) ;
// The 'dirDepth' option above is set to 3 so the output will be similar to the following:
// '/e44d3b0d-b552-4257-8b64-a53331184c38/443061b9-bfa7-40fc-a5a9-d848bc52155e/4d818f4c-88b3-45fd-a104-a2fc3700e9de'
} catch ( err ) {
console . error ( err ) ;
}
}
main ( ) ;setCurrentBlobDir(blobDir)ประเภท: วิธีการ
พารามิเตอร์: blobDir เป็น String
blobStoreRoot ผลตอบแทน: Promise ที่แก้ไข undefined
คำอธิบาย:
ฟังก์ชั่นนี้สามารถใช้เพื่อเป็นแนวทาง BlobStore เพื่อบันทึกไฟล์ blob ใหม่ลงใน blobPath ที่ต้องการ
ปัญหาหนึ่งของ scalable-blob-store คือถ้าคุณลบไฟล์ blob จำนวนมากไดเรกทอรีที่ไฟล์อยู่ในนั้นจะไม่ถูกลบออก คุณสามารถลบไดเรกทอรีด้วยตัวเองหรือ repopulate ด้วยไฟล์ blob ใหม่โดยการตั้งค่าไดเรกทอรี Blob ที่ใช้งานอยู่ในปัจจุบัน
ฟังก์ชั่นนี้ถูกเพิ่มเพื่อให้ผู้บริโภคของโมดูลนี้สามารถแก้ไขไดเรกทอรี Blob ที่ว่างเปล่า
ตัวอย่าง:
const BlobStore = require ( 'scalable-blob-store' ) ;
const uuid = require ( 'uuid' ) ;
const options = {
blobStoreRoot : '/app/blobs' ,
idFunction : uuid . v4 ,
dirDepth : 3 ,
dirWidth : 2000 ,
} ;
const blobStore = new BlobStore ( options ) ;
async function main ( ) {
try {
console . log ( await blobStore . getCurrentBlobDir ( ) ) ;
// The 'dirDepth' option above is set to 3 so the output will be similar to the following:
// '/e44d3b0d-b552-4257-8b64-a53331184c38/443061b9-bfa7-40fc-a5a9-d848bc52155e/4d818f4c-88b3-45fd-a104-a2fc3700e9de'
await blobStore . setCurrentBlobDir ( '/some/blob/path' ) ;
console . log ( await blobStore . getCurrentBlobDir ( ) ) ;
// Outputs '/some/blob/path' to the console.
// Any new blob files added to the blob store will go into this path until there are `dirWidth` or 2000 files within it.
} catch ( err ) {
console . error ( err ) ;
}
}
main ( ) ;createWriteStream()ประเภท: วิธีการ
Returns : Promise ที่แก้ไขไปยัง Object ที่มีเส้นทางลูกไปยังไฟล์ภายในรูบรูทบล็อบสโตร์และ writestream
คำอธิบาย:
นี่คือ exampe ของวัตถุที่ส่งคืนโดยใช้ UUID เป็น idfunction:
{
blobPath : "/e6b7815a-c818-465d-8511-5a53c8276b86/aea4be6a-9e7f-4511-b394-049e68f59b02/fea722d1-001a-4765-8408-eb8e0fe7dbc6/183a6b7b-2fd6-4f80-8c6a-2647beb7bb19" ,
writeStream : stream . Writable
} ใช้ writeStream เพื่อบันทึกหยดหรือไฟล์ของคุณ blobPath จะต้องบันทึกลงในฐานข้อมูลของคุณเพื่อการเข้าถึงในอนาคต
ตัวอย่าง:
const BlobStore = require ( 'scalable-blob-store' ) ;
const uuid = require ( 'uuid' ) ;
const options = {
blobStoreRoot : '/app/blobs' ,
idFunction : uuid . v4 ,
dirDepth : 3 ,
dirWidth : 2000 ,
} ;
const blobStore = new BlobStore ( options ) ;
// The below readStream is simply to make this a complete example
const fs = require ( 'fs' ) ;
const readStream = fs . createReadStream ( '/path/to/file' ) ;
async function main ( ) {
let result ;
try {
result = await blobStore . createWriteStream ( ) ;
} catch ( err ) {
console . error ( err ) ;
}
console . dir ( result ) ;
// result object will be similar to this:
// {
// blobPath: "/e6b7815a-c818-465d-8511-5a53c8276b86/aea4be6a-9e7f-4511-b394-049e68f59b02/fea722d1-001a-4765-8408-eb8e0fe7dbc6/183a6b7b-2fd6-4f80-8c6a-2647beb7bb19",
// writeStream: [WriteStream]
// }
// Using a Promise to encapsulate the write asynchronous events.
await new Promise ( ( resolve , reject ) => {
result . writeStream . on ( 'finish' , ( ) => {
resolve ( ) ;
} ) ;
result . writeStream . on ( 'error' , reject ) ;
readStream . pipe ( result . writeStream ) ;
} ) ;
console . log ( blobPath ) ;
// Logs the blobPath. Save this in your database.
}
main ( ) ;write(data, writeOptions)ประเภท: วิธีการ
พารามิเตอร์: data เป็น String , Buffer , TypedArray หรือ DataView
พารามิเตอร์: writeOptions เป็น Object
writeOptions รองรับคุณสมบัติการเข้ารหัสโหมดและการตั้งค่าสถานะ Returns: Promise ที่แก้ไขเป็น String
blobPath ซึ่งต้องการการส่งฐานข้อมูลของคุณคำอธิบาย:
หากคุณมีข้อมูลอย่างง่ายในหน่วยความจำมากกว่ากระแสข้อมูลคุณสามารถใช้วิธีนี้เพื่อจัดเก็บข้อมูลลงในไฟล์ BLOB
ตัวอย่าง:
const BlobStore = require ( 'scalable-blob-store' ) ;
const uuid = require ( 'uuid' ) ;
const options = {
blobStoreRoot : '/app/blobs' ,
idFunction : uuid . v4 ,
dirDepth : 3 ,
dirWidth : 2000 ,
} ;
const blobStore = new BlobStore ( options ) ;
async function main ( ) {
const data = 'The quick brown fox jumps over the lazy dog.' ;
try {
const blobPath = await blobStore . write ( data ) ;
// The returned blobPath will look something like this:
// '/e44d3b0d-b552-4257-8b64-a53331184c38/443061b9-bfa7-40fc-a5a9-d848bc52155e/4d818f4c-88b3-45fd-a104-a2fc3700e9de'
// Save it to your database.
} catch ( err ) {
console . error ( err ) ;
}
}
main ( ) ;append(blobPath, data, appendOptions)ประเภท: วิธีการ
พารามิเตอร์: blobPath เป็น String
blobPath จากฐานข้อมูลแอปพลิเคชันของคุณ พารามิเตอร์: data เป็น String หรือ Buffer
พารามิเตอร์: appendOptions เป็น Object
appendOptions รองรับการเข้ารหัสโหมดและคุณสมบัติการตั้งค่าสถานะ Returns: Promise ที่แก้ไขให้ undefined
คำอธิบาย:
ใช้วิธีนี้เพื่อเพิ่มข้อมูลหน่วยความจำอย่างง่ายในตอนท้ายของไฟล์ Blob
ตัวอย่าง:
const BlobStore = require ( 'scalable-blob-store' ) ;
const uuid = require ( 'uuid' ) ;
const options = {
blobStoreRoot : '/app/blobs' ,
idFunction : uuid . v4 ,
dirDepth : 3 ,
dirWidth : 2000 ,
} ;
const blobStore = new BlobStore ( options ) ;
async function main ( ) {
const data = 'The quick brown fox jumps over the lazy dog.' ;
try {
await blobStore . append ( data ) ;
} catch ( err ) {
console . error ( err ) ;
}
}
main ( ) ;copy(blobPath, flags)ประเภท: วิธีการ
พารามิเตอร์: blobPath เป็น String
blobPath จากฐานข้อมูลแอปพลิเคชันของคุณ พารามิเตอร์: flags เป็น Number
Returns: Promise ที่แก้ไขเป็น String
blobPath ใหม่สำหรับไฟล์ blob ที่คัดลอกคำอธิบาย:
ใช้วิธีนี้เพื่อสร้างสำเนาของไฟล์ Blob ที่มีอยู่
ตัวอย่าง:
const BlobStore = require ( 'scalable-blob-store' ) ;
const uuid = require ( 'uuid' ) ;
const options = {
blobStoreRoot : '/app/blobs' ,
idFunction : uuid . v4 ,
dirDepth : 3 ,
dirWidth : 2000 ,
} ;
const blobStore = new BlobStore ( options ) ;
async function main ( ) {
try {
const blobPathSource =
'/e6b7815a-c818-465d-8511-5a53c8276b86/aea4be6a-9e7f-4511-b394-049e68f59b02/fea722d1-001a-4765-8408-eb8e0fe7dbc6/183a6b7b-2fd6-4f80-8c6a-2647beb7bb19' ;
const blobPathDest = await blobStore . copy ( blobPathSource ) ;
// Store your new blobPath into your application database
} catch ( err ) {
console . error ( err ) ;
}
}
main ( ) ;createReadStream(blobPath)ประเภท: วิธีการ
พารามิเตอร์: blobPath เป็น String
blobPath จากฐานข้อมูลแอปพลิเคชันของคุณ Returns : Promise ที่แก้ไขให้กับ ReadStream
คำอธิบาย:
สร้างสตรีมที่อ่านได้ไปยังไฟล์ blob ที่อยู่ที่ blobPath
ตัวอย่าง:
const BlobStore = require ( 'scalable-blob-store' ) ;
const uuid = require ( 'uuid' ) ;
const options = {
blobStoreRoot : '/app/blobs' ,
idFunction : uuid . v4 ,
dirDepth : 3 ,
dirWidth : 2000 ,
} ;
async function main ( ) {
// Get the blobPath value from your database.
const blobPath =
'/e6b7815a-c818-465d-8511-5a53c8276b86/aea4be6a-9e7f-4511-b394-049e68f59b02/fea722d1-001a-4765-8408-eb8e0fe7dbc6/183a6b7b-2fd6-4f80-8c6a-2647beb7bb19h' ;
let readStream ;
try {
readStream = await blobStore . createReadStream ( blobPath ) ;
} catch ( err ) {
console . error ( err ) ;
}
readStream . on ( 'error' , ( err ) => {
console . error ( err ) ;
} ) ;
// Blob contents is piped to the console.
readStream . pipe ( process . stdout ) ;
}
main ( ) ;read(blobPath, readOptions)ประเภท: วิธีการ
พารามิเตอร์: blobPath เป็น String
blobPath จากฐานข้อมูลแอปพลิเคชันของคุณ พารามิเตอร์: readOptions เป็น Object
Returns: Promise ที่แก้ไขเนื้อหาของไฟล์ Blob
scalable-blob-store ตั้งค่า readOptions.encoding ค่าเป็น 'UTF8' โดยค่าเริ่มต้นคำอธิบาย:
ใช้วิธีนี้เพื่ออ่านเนื้อหาของไฟล์ Blob ขนาดเล็กลงในหน่วยความจำ
ตัวอย่าง:
const BlobStore = require ( 'scalable-blob-store' ) ;
const uuid = require ( 'uuid' ) ;
const options = {
blobStoreRoot : '/app/blobs' ,
idFunction : uuid . v4 ,
dirDepth : 3 ,
dirWidth : 2000 ,
} ;
const blobStore = new BlobStore ( options ) ;
async function main ( ) {
try {
// Retrieve the blobPath value from your database
const blobPath =
'/e6b7815a-c818-465d-8511-5a53c8276b86/aea4be6a-9e7f-4511-b394-049e68f59b02/fea722d1-001a-4765-8408-eb8e0fe7dbc6/183a6b7b-2fd6-4f80-8c6a-2647beb7bb19' ;
const content = await blobStore . read ( blobPath ) ;
// Do something with the content
} catch ( err ) {
console . error ( err ) ;
}
}
main ( ) ;open(blobPath, flags, mode)ประเภท: วิธีการ
พารามิเตอร์: blobPath เป็น String
blobPath จากฐานข้อมูลแอปพลิเคชันของคุณ พารามิเตอร์: flags เป็น String หรือ Number
Returns: Promise ที่แก้ไขไปยังวัตถุ FileHandle
คำอธิบาย:
นี่เป็นวิธีการขั้นสูงที่ช่วยให้คุณดำเนินการไฟล์จำนวนมากกับไฟล์ Blob
ตัวอย่าง:
const BlobStore = require ( 'scalable-blob-store' ) ;
const uuid = require ( 'uuid' ) ;
const options = {
blobStoreRoot : '/app/blobs' ,
idFunction : uuid . v4 ,
dirDepth : 3 ,
dirWidth : 2000 ,
} ;
const blobStore = new BlobStore ( options ) ;
async function main ( ) {
try {
// Retrieve the blobPath value from your database
const blobPath =
'/e6b7815a-c818-465d-8511-5a53c8276b86/aea4be6a-9e7f-4511-b394-049e68f59b02/fea722d1-001a-4765-8408-eb8e0fe7dbc6/183a6b7b-2fd6-4f80-8c6a-2647beb7bb19' ;
const fileHandle = await blobStore . open ( blobPath ) ;
// Do something with the file handle object
// See the documentation for more detail
// The documentation link is in the description above
} catch ( err ) {
console . error ( err ) ;
}
}
main ( ) ;realPath(blobPath, realPathOptions)ประเภท: วิธีการ
พารามิเตอร์: blobPath เป็น String
blobPath จากฐานข้อมูลแอปพลิเคชันของคุณ พารามิเตอร์: realPathOptions เป็น String หรือ Object
Returns: Promise ที่แก้ไขเป็น String
คำอธิบาย:
ใช้วิธีนี้เพื่อค้นหาไฟล์ blob บนระบบไฟล์ วิธีนี้ไม่ควรจำเป็นเพราะคุณสามารถกำหนดเส้นทางไฟล์ BLOB เต็มรูปแบบ เพียงแค่เชื่อมต่อ blobstoreroot และค่า blobpath
ตัวอย่าง:
const BlobStore = require ( 'scalable-blob-store' ) ;
const uuid = require ( 'uuid' ) ;
const options = {
blobStoreRoot : '/app/blobs' ,
idFunction : uuid . v4 ,
dirDepth : 3 ,
dirWidth : 2000 ,
} ;
const blobStore = new BlobStore ( options ) ;
async function main ( ) {
try {
// Retrieve the blobPath value from your database
const blobPath =
'/e6b7815a-c818-465d-8511-5a53c8276b86/aea4be6a-9e7f-4511-b394-049e68f59b02/fea722d1-001a-4765-8408-eb8e0fe7dbc6/183a6b7b-2fd6-4f80-8c6a-2647beb7bb19' ;
const fsPath = await blobStore . realPath ( blobPath ) ;
// With the above options the result will be similar to this:
// '/app/blobs/e6b7815a-c818-465d-8511-5a53c8276b86/aea4be6a-9e7f-4511-b394-049e68f59b02/fea722d1-001a-4765-8408-eb8e0fe7dbc6/183a6b7b-2fd6-4f80-8c6a-2647beb7bb19
} catch ( err ) {
console . error ( err ) ;
}
}
main ( ) ;stat(blobPath)ประเภท: วิธีการ
พารามิเตอร์: blobPath เป็น String
ผลตอบแทน: Object สถิติ
คำอธิบาย:
แทนที่จะแยกวิเคราะห์วัตถุระบบ stats ไฟล์ scalable-blob-store จะส่งคืนวัตถุ stats ดิบ
รายละเอียดชั้นเรียนสถิติเพิ่มเติมสามารถพบได้ใน Wikipedia
ตัวอย่าง:
const BlobStore = require ( 'scalable-blob-store' ) ;
const uuid = require ( 'uuid' ) ;
const options = {
blobStoreRoot : '/app/blobs' ,
idFunction : uuid . v4 ,
dirDepth : 3 ,
dirWidth : 2000 ,
} ;
const blobStore = new BlobStore ( options ) ;
async function main ( ) {
try {
// Retrieve the blobPath value from your database
const blobPath =
'/e6b7815a-c818-465d-8511-5a53c8276b86/aea4be6a-9e7f-4511-b394-049e68f59b02/fea722d1-001a-4765-8408-eb8e0fe7dbc6/183a6b7b-2fd6-4f80-8c6a-2647beb7bb19' ;
const stats = await blobStore . stat ( blobPath ) ;
console . dir ( stats ) ;
// Console output will be similar to the following.
// { dev: 2050,
// mode: 33188,
// nlink: 1,
// uid: 1000,
// gid: 1000,
// rdev: 0,
// blksize: 4096,
// ino: 6707277,
// size: 44,
// blocks: 8,
// atime: Mon Oct 12 2015 08:51:29 GMT+1000 (AEST),
// mtime: Mon Oct 12 2015 08:51:29 GMT+1000 (AEST),
// ctime: Mon Oct 12 2015 08:51:29 GMT+1000 (AEST),
// birthtime: Mon Oct 12 2015 08:51:29 GMT+1000 (AEST) }
} catch ( err ) {
console . error ( err ) ;
}
}
main ( ) ;exists(blobPath)ประเภท: วิธีการ
พารามิเตอร์: blobPath เป็น String
ผลตอบแทน: Boolean
true ถ้าไฟล์มีอยู่มิฉะนั้น falseคำอธิบาย:
ใช้วิธีนี้สำหรับการทดสอบการดำรงอยู่ของไฟล์ Blob อย่างง่าย
ตัวอย่าง:
const BlobStore = require ( 'scalable-blob-store' ) ;
const uuid = require ( 'uuid' ) ;
const options = {
blobStoreRoot : '/app/blobs' ,
idFunction : uuid . v4 ,
dirDepth : 3 ,
dirWidth : 2000 ,
} ;
const blobStore = new BlobStore ( options ) ;
async function main ( ) {
try {
// Retrieve the blobPath value from your database
const blobPath =
'/e6b7815a-c818-465d-8511-5a53c8276b86/aea4be6a-9e7f-4511-b394-049e68f59b02/fea722d1-001a-4765-8408-eb8e0fe7dbc6/183a6b7b-2fd6-4f80-8c6a-2647beb7bb19' ;
const exists = await blobStore . exists ( blobPath ) ;
// The result will be either true or false depending if the blob file exists.
} catch ( err ) {
console . error ( err ) ;
}
}
main ( ) ;remove(blobPath)ประเภท: วิธีการ
พารามิเตอร์: blobPath เป็น String
Returns : undefined หากไม่มีอะไรผิดปกติหรือไม่มีไฟล์
คำอธิบาย:
ใช้วิธีนี้เพื่อลบไฟล์ Blob วิธีนี้ไม่สามารถใช้เพื่อลบไดเรกทอรี
ตัวอย่าง:
const BlobStore = require ( 'scalable-blob-store' ) ;
const uuid = require ( 'uuid' ) ;
const options = {
blobStoreRoot : '/app/blobs' ,
idFunction : uuid . v4 ,
dirDepth : 3 ,
dirWidth : 2000 ,
} ;
const blobStore = new BlobStore ( options ) ;
async function main ( ) {
try {
// Retrieve the blobPath value from your database
const blobPath =
'/e6b7815a-c818-465d-8511-5a53c8276b86/aea4be6a-9e7f-4511-b394-049e68f59b02/fea722d1-001a-4765-8408-eb8e0fe7dbc6/183a6b7b-2fd6-4f80-8c6a-2647beb7bb19' ;
await blobStore . remove ( blobPath ) ;
// The blob file will no longer exist
} catch ( err ) {
console . error ( err ) ;
}
}
main ( ) ; มีปัญหาเล็กน้อยใน scalable-blob-store หากมีการเพิ่มไฟล์ blob จำนวนมากแล้วลบออกจากร้านค้า Blob คุณอาจมีไดเรกทอรีหรือไดเรกทอรีที่ว่างเปล่าที่มีไฟล์จำนวนน้อยอยู่ในนั้น ไดเรกทอรีเหล่านี้จะไม่ถูกลบออกและจะไม่ถูกเติม
หากคุณต้องการป้องกันไดเรกทอรีที่ว่างเปล่าหรือมีประชากรเบาบางคุณจะต้องทำงานการบำรุงรักษากับไดเรกทอรี blobStoreRoot งานการบำรุงรักษานี้จะต้องมองหาไดเรกทอรีที่ว่างเปล่าหรือไม่สมบูรณ์และเรียกใช้วิธี setCurrentBlobdir ที่ผ่านใน blobPath ที่ว่างเปล่า
สำหรับแอปพลิเคชันของคุณคุณอาจพบว่าคุณไม่ค่อยลบไฟล์ BLOB จำนวนมาก หากเป็นกรณีนี้ปัญหานี้สามารถละเว้นได้
มีสองวิธีในการทดสอบ scalable-blob-store :
os.tmpdir() หลังจากโคลนนิ่ง scalable-blob-store ให้พิมพ์ต่อไปนี้ลงในคอนโซลของคุณ:
npm install
npm test
การรันไฟล์ test-fs.js จะสร้างไดเรกทอรี ~/blobs ในไดเรกทอรีชั่วคราวของคุณจากนั้นเติมเต็มด้วย blobs จำนวนมาก
ตัวเลือกเริ่มต้นที่กำหนดค่าในไฟล์ test-fs.js คือ:
const opts = {
blobStoreRoot : os . tmpdir ( ) + '/blobs' ,
idFunction : cuid ,
dirDepth : 3 ,
dirWidth : 1000 ,
} ;
const repeat = 10000 ;เปลี่ยนตัวเลือกหากคุณต้องการดูผลลัพธ์ที่แตกต่างกัน
หลังจากโคลนนิ่ง scalable-blob-store ให้พิมพ์ต่อไปนี้ลงในคอนโซลของคุณ:
npm install
node ./tests/test-fs.js
เมื่อเสร็จสิ้นแล้วให้ตรวจสอบไดเร็กทอรี /tmp/blobs ฉันขอแนะนำให้ใช้คำสั่ง Tree ซึ่งให้ข้อมูลสรุปของไดเรกทอรีและไฟล์ภายในไดเรกทอรีเป้าหมาย
tree ~ /blobs
tree -d ~ /blobs
ฉัน Grant Carthew เป็นนักเทคโนโลยีจากรัฐควีนส์แลนด์ประเทศออสเตรเลีย ฉันทำงานเกี่ยวกับรหัสในโครงการส่วนบุคคลจำนวนมากและเมื่อความต้องการเกิดขึ้นฉันก็สร้างแพ็คเกจของตัวเอง
โครงการนี้มีอยู่เพราะฉันต้องการร้านค้า Blob ท้องถิ่นที่สามารถปรับขนาดได้
ทุกสิ่งที่ฉันทำในโอเพ่นซอร์สจะทำในเวลาของฉันเองและเพื่อสนับสนุนชุมชนโอเพ่นซอร์ส
หากคุณใช้โครงการของฉันและขอขอบคุณหรือสนับสนุนฉันโปรดคลิกลิงก์ Patreon ด้านล่าง
ดูโครงการอื่น ๆ ของฉันใน NPM
git checkout -b my-new-featuregit commit -am 'Add some feature'git push origin my-new-featurenode-uuid ด้วย uuidES5 ลบข้อกำหนดของเครื่องยนต์ NodeJSreturn null มากขึ้นreturn null หลังจากการแก้ไข/ปฏิเสธการโทรเพื่อป้องกันการเตือนบลูเบิร์ดes5dist สำหรับโหนดรุ่นเก่า อัปเดตแพ็คเกจมิกซ์