Ein Dateisystem -Blob -Store, der Konflikte verhindern soll, wenn sie mit einem verteilten Dateisystem oder einem Speicherbereichsnetzwerk verwendet werden.
Bitte spielen Sie auf Github / NPM und achten Sie auf Updates.
Hinweis: Erfordert Node.js v12 oder höher.
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.Weitere Details finden Sie in den Beispieldateien zum Quick Start -Beispiel:
Nach der Recherche von Benutzerdateispeichern oder Blob -Speicher für eine Webanwendung, an der ich gearbeitet habe, habe ich festgestellt, dass die häufigste Lösung von Webentwicklern darin besteht, Dateien mit einem Cloud -Dienstanbieter zu speichern. Nachdem sie ein Konto bei Anbietern wie Amazon S3, Google Cloud -Speicher oder Azure -Speicher erstellt haben, verstärken sie dort nur alle Anwendungsdateien und Blobs.
Ich recherchierte den Preis für Cloud -Speicher und entschied, dass ich eine kostenlose lokale Version haben wollte, die bei Bedarf skalieren würde.
Ich habe mir eine Reihe bestehender Lösungen wie FileStorage angesehen, war aber mit der Skalierbarkeit dieser Lösungen unzufrieden. Die meisten sind nur für einen einzelnen Server ausgelegt und würden Schreibkonflikte verursachen, wenn ein verteiltes Dateisystem, ein Cluster -Dateisystem wie Glusterfs oder ein Speicher -Netzwerk als Backend -Dateisystem verwendet wurde.
Auf einer langen Autofahrt dachte ich über eine Lösung für meinen Blob-Speicher nach und entwickelte scalable-blob-store .
Um eine Skalierbarkeit eines verteilten oder replizierten Dateisystems zu erreichen, verwendet scalable-blob-store keine Indexdateien oder andere Datenbanken, um die Dateien auf dem Festplatten- oder Speichersystem zu verwalten. Stattdessen wird das Dateisystem selbst verwendet, um den neuesten Speicherpfad basierend auf dem birthtime -Attribut für Dateisysteme (das Datum der Verzeichniserstellung) zu finden.
Sobald der neueste Pfad ermittelt wurde, wird die Anzahl der Dateien innerhalb des Verzeichnisses gezählt, um sicherzustellen, dass er unter dem konfigurierten Wert bleibt. Dies soll Probleme mit der Leistung von Festplatten verhindern, wenn eine sehr große Anzahl von Dateien in einem einzigen Verzeichnis gespeichert wird. Wenn die Anzahl der Elemente innerhalb eines Verzeichnisses zu groß wird, wird ein neuer Speicherpfad ermittelt.
Da keine Datenbanken verwendet werden, um die Dateien im Root -Pfad zu verwalten, müssen Sie den zurückgegebenen blobPath -Wert und die Metadaten über die gespeicherten Dateien in Ihrer eigenen Datenbank beibehalten.
Der Grund, warum scalable-blob-store skalierbar ist, ist die Benennung der Verzeichnisse und Dateien in Ihrem Dateisystem. Jedes Verzeichnis und jede Datei, die auf der Festplatte gespeichert ist, wird von einer generierten eindeutigen ID bezeichnet, die auf einem benutzerdefinierten Funciton basiert. Sie können einen eindeutigen ID -Generator wie Ulid-, Cuid-, UUID -V4- oder Mongodbs -Objektids verwenden, um nur einige zu nennen. Weitere Beispiele finden Sie in meinem fantastischen eindeutigen ID -Repository. Das Zusammenführen von Verzeichnissen zwischen Servern oder Festplatten sollte niemals Kollisionen von Dateinamen verursachen.
Wenn ein repliziertes oder ein Cluster -Dateisystem verwendet wird, kann der einzige Konflikt auftreten, wenn ein Server eine Datei liest, während ein anderer dieselbe Datei entfernt. scalable-blob-store versucht nicht, diesen Konflikt zu verwalten, es wird jedoch die Ausnahme erheben.
Im Folgenden finden Sie Beispiele für die Verzeichnisstruktur, die durch scalable-blob-store erstellt wurde.
Beispiel mit Cuid -Verzeichnis und Dateinamen:
b lobs c ij50xia200pzzph3we9r62bi // ← Directory File ↓
b lobs c ij50xia300q1zph3m4df4ypz . . c ij50xiae00qgzph3i0ms0l2wBeispiel mit UUID -Verzeichnis und Dateinamen:
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 unterstützt Konfigurationsoptionen, um Ihnen die Kontrolle über die verwendeten Verzeichnisse und die Datei-IDs, die Tiefe der Verzeichnisstruktur und die Breite der Verzeichnisse zu erhalten. Die Standardoptionen bieten 3 Verzeichnisse tief, die 1000 Elemente enthalten, die einen Gesamtspeicher von einer Milliarde Dateien innerhalb der Verzeichnisstruktur enthalten.
Andere operative Punkte von Interesse:
dirWidth -Wert erreicht hat, wird das nächste Verzeichnis erstellt.dirWidth -Wert erreicht hat, wird das nächste übergeordnete Verzeichnis erstellt.dirWidth -Wert erreicht hat, wird der dirWidth -Wert ignoriert. Schreiben
Auf meinem Laptop mit einer M.2 SSD-Festplatte erzeugt das Ausführen des Test-Fs.js-Skripts die folgenden Ergebnisse:
====================================================================================================
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.
====================================================================================================
Lesen
Die Leseleistung ist nahe, wenn nicht sogar der Festplattengeschwindigkeit.
Alle Blobin-Methoden in scalable-blob-store geben ein Versprechen zurück. Dies ist perfekt für die Verwendung der Async/Ause Aused Language -Funktionen.
| API | Typ | Zurück |
|---|---|---|
| Neue Blobin (Optionen) | Konstruktor | Blobin -Instanz |
| bloBstore.bloBstoreroot | Lesen Sie nur Eigentum | String |
| BloBstore.Idfunction | Lesen Sie nur Eigentum | Function |
| bloBstore.dirdepth | Lesen Sie nur Eigentum | Number |
| bloBstore.dirwidth | Lesen Sie nur Eigentum | Number |
| bloBstore.getCurrentBlobdir ()) | Verfahren | Promise<String> |
| BLOBSTORE.SETCURRENTBLOBDIR (BLOBDIR) | Verfahren | Promise<undefined> |
| BloBstore.Createwritestream () | Verfahren | Promise<Object> |
| bloBstore.write (Daten, Schreibungen) | Verfahren | Promise<String> |
| BloBstore.Append (Blobpath, Daten, Anhänge) | Verfahren | Promise<undefined> |
| bloBstore.copy (Blobpath, Flaggen) | Verfahren | Promise<String> |
| bloBstore.createadstream (Blobpath) | Verfahren | Promise<ReadStream> |
| BloBstore.read (Blobpath, Readoptions) | Verfahren | Promise<data> |
| bloBstore.open (Blobpath, Flags, Modus) | Verfahren | Promise<FileHandle> |
| BloBstore.realPath (Blobpath, RealPathoptions) | Verfahren | Promise<String> |
| bloBstore.stat (Blobpath) | Verfahren | Promise<Stats> |
| bloBstore.exists (Blobpath) | Verfahren | Promise<Boolean> |
| bloBstore.remove (Blobpath) | Verfahren | Promise<undefined> |
new BlobStore(options)Typ: Konstruktorfunktion.
Parameter: options als Object .
Rückgabe : Ein neues BlobStore -Objekt, mit dem Daten gespeichert werden sollen.
Beschreibung:
Sie können mehrmals new BlobStore(options) anrufen, um mehr als einen Blob -Store zu erstellen.
Optionen werden als JavaScript object an die Konstruktorfunktion übergeben.
| Schlüssel | Beschreibung | Standardeinstellungen |
|---|---|---|
blobStoreRoot | Root -Verzeichnis zum Speichern von Blobs | Erforderlich |
idFunction | Jede ID -Funktion, die eine eindeutige ID -Zeichenfolge zurückgibt | Erforderlich |
dirDepth | Wie tief Sie die Verzeichnisse unter der Wurzel wollen | 3 |
dirWidth | Die maximale Anzahl von Dateien oder Verzeichnissen in einem Verzeichnis | 1000 |
Beispiel:
// 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 ) ;Erstellen mehrerer Blob -Stores:
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 ) ;blobStoreRootTyp: Lesen Sie nur Eigenschaft.
Rückgaben: Eine String , die Ihren options.blobStoreRoot entspricht.
Beschreibung:
Dies ist eine Convenience -Eigenschaft, mit der Sie das BloBstore -Objekt an ein Submodul übergeben und weiterhin auf die konfigurierten Eigenschaften zugreifen können.
Beispiel:
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 optionsidFunctionTyp: Lesen Sie nur Eigenschaft.
Rückgaben: Die eindeutige ID -Funktion, die Sie in den options.idFunction konfiguriert haben.
Beschreibung:
Dies ist eine Convenience -Eigenschaft, mit der Sie das BloBstore -Objekt an ein Submodul übergeben und weiterhin auf die konfigurierten Eigenschaften zugreifen können.
Beispiel:
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.dirDepthTyp: Lesen Sie nur Eigenschaft.
Rückgaben: Eine Number , die Ihren options.dirDepth entspricht.
Beschreibung:
Dies ist eine Convenience -Eigenschaft, mit der Sie das BloBstore -Objekt an ein Submodul übergeben und weiterhin auf die konfigurierten Eigenschaften zugreifen können.
Beispiel:
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 optionsdirWidthTyp: Lesen Sie nur Eigenschaft.
Rückgaben: Eine Number , die Ihren options.dirWidth entspricht. Dirwidth Value.
Beschreibung:
Dies ist eine Convenience -Eigenschaft, mit der Sie das BloBstore -Objekt an ein Submodul übergeben und weiterhin auf die konfigurierten Eigenschaften zugreifen können.
Beispiel:
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()Typ: Methode.
Rückgabe: Ein Promise , das sich auf eine String beschließt, die das aktuelle aktive Blob -Erstellungsverzeichnis ist.
Beschreibung:
Diese Funktion wird intern vom BlobStore verwendet, um das Verzeichnis zu bestimmen, in dem die nächste Blob -Datei auf der Festplatte gespeichert wird.
Wenn Sie jemals eine Blob -Datei außerhalb des BlobStore speichern müssen, können Sie diese Methode verwenden, um den richtigen Ort für die Einstellung Ihrer Datei zu finden.
Beispiel:
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)Typ: Methode.
Parameter: blobDir als String .
blobStoreRoot -Pfad befindet. Rückkehr: Ein Promise , das sich zu undefined beschließt.
Beschreibung:
Diese Funktion kann verwendet werden, um den BlobStore zu leiten, um neue Blob -Dateien in einen gewünschten blobPath zu speichern.
Ein Problem mit scalable-blob-store ist, dass die Verzeichnisse, in denen sich die Dateien befanden, nicht entfernt werden, wenn Sie viele Blob-Dateien entfernen. Sie können entweder die Verzeichnisse selbst entfernen oder sie mit neuen Blob -Dateien neu bevölkern, indem Sie das aktuelle aktive Blob -Verzeichnis einstellen.
Diese Funktion wurde hinzugefügt, um den Verbrauchern dieses Moduls zu ermöglichen, leere Blob -Verzeichnisse zu arbeiten.
Beispiel:
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()Typ: Methode.
Rückgabe : Ein Promise , das sich in ein Object enthält, das den untergeordneten Pfad zur Datei im Blob Store Root und einen WriteStream enthält.
Beschreibung:
Hier ist ein Exampe des zurückgegebenen Objekts mit UUID als IDfunktion:
{
blobPath : "/e6b7815a-c818-465d-8511-5a53c8276b86/aea4be6a-9e7f-4511-b394-049e68f59b02/fea722d1-001a-4765-8408-eb8e0fe7dbc6/183a6b7b-2fd6-4f80-8c6a-2647beb7bb19" ,
writeStream : stream . Writable
} Verwenden Sie den writeStream , um Ihren Blob oder Ihre Datei zu speichern. Der blobPath muss für den zukünftigen Zugriff in Ihrer Datenbank gespeichert werden.
Beispiel:
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)Typ: Methode.
Parameter: data als String , Buffer , TypedArray oder DataView .
Parameter: writeOptions als Object .
writeOptions -Objekt unterstützt eine Codierung, Modus und Flag -Eigenschaft. Rückgabe: Ein Promise , das sich in eine String entscheidet.
blobPath -Wert, der sich für Ihre Datenbank verpflichten muss.Beschreibung:
Wenn Sie einfache Daten im Speicher und nicht einen Datenstrom haben, können Sie diese Methode verwenden, um die Daten in einer Blob -Datei zu speichern.
Beispiel:
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)Typ: Methode.
Parameter: blobPath als String .
blobPath aus Ihrer Anwendungsdatenbank ab. Parameter: data als String oder Buffer .
Parameter: appendOptions als Object .
appendOptions -Objekt unterstützt eine Codierungs-, Modus- und Flag -Eigenschaft. Rückkehr: Ein Promise , das sich auf einen undefined entscheidet.
Beschreibung:
Verwenden Sie diese Methode, um einfach in Speicherdaten zum Ende der Blob -Datei hinzuzufügen.
Beispiel:
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)Typ: Methode.
Parameter: blobPath als String .
blobPath aus Ihrer Anwendungsdatenbank ab. Parameter: flags als Number .
Rückgabe: Ein Promise , das sich in eine String entscheidet.
blobPath -Wert für die kopierte Blob -Datei.Beschreibung:
Verwenden Sie diese Methode, um eine Kopie einer vorhandenen Blob -Datei zu erstellen.
Beispiel:
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)Typ: Methode.
Parameter: blobPath als String .
blobPath aus Ihrer Anwendungsdatenbank ab. Rückgabe : Ein Promise , das sich auf einen ReadStream beschließt.
Beschreibung:
Erstellt einen lesbaren Stream zur Blob -Datei am blobPath .
Beispiel:
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)Typ: Methode.
Parameter: blobPath als String .
blobPath aus Ihrer Anwendungsdatenbank ab. Parameter: readOptions als Object .
Rückgabe: Ein Promise , das sich auf den Inhalt der Blob -Datei beschließt.
scalable-blob-store legt den readOptions.encoding -Wert standardmäßig auf 'UTF8' fest.Beschreibung:
Verwenden Sie diese Methode, um den Inhalt einer kleinen Blob -Datei in den Speicher zu lesen.
Beispiel:
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)Typ: Methode.
Parameter: blobPath als String .
blobPath aus Ihrer Anwendungsdatenbank ab. Parameter: flags als String oder Number .
Rückgabe: Ein Promise , das sich in ein DateiHandle -Objekt entscheidet.
Beschreibung:
Dies ist eine fortgeschrittenere Methode, mit der Sie viele Dateioperationen gegen die Blob -Datei durchführen können.
Beispiel:
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)Typ: Methode.
Parameter: blobPath als String .
blobPath aus Ihrer Anwendungsdatenbank ab. Parameter: realPathOptions als String oder Object .
Rückgabe: Ein Promise , das sich in eine String entscheidet.
Beschreibung:
Verwenden Sie diese Methode, um eine Blob -Datei im Dateisystem zu finden. Diese Methode sollte nicht wirklich benötigt werden, da Sie den vollständigen Blob -Dateipfad bestimmen können. Verkettieren Sie einfach die Werte von Blobstoreroot und Blobpath.
Beispiel:
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)Typ: Methode.
Parameter: blobPath als String .
Rückgabe: Ein Object .
Beschreibung:
Anstatt das Objekt des stats zu analysieren, gibt scalable-blob-store das RAW stats zurück.
Weitere Datenklassendetails finden Sie in Wikipedia.
Beispiel:
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)Typ: Methode.
Parameter: blobPath als String .
Rückkehr: Boolean
true wenn die Datei existiert, sonst false .Beschreibung:
Verwenden Sie diese Methode für einen einfachen Blob -Datei -Existenztest.
Beispiel:
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)Typ: Methode.
Parameter: blobPath als String .
Rückgaben : undefined , wenn nichts schief ging oder die Datei nicht existierte.
Beschreibung:
Verwenden Sie diese Methode, um eine Blob -Datei zu löschen. Diese Methode kann nicht zum Entfernen von Verzeichnissen verwendet werden.
Beispiel:
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 ( ) ; Es gibt ein kleines Problem im scalable-blob-store . Wenn eine große Anzahl von Blob -Dateien hinzugefügt und dann aus dem Blob -Store entfernt werden, können Sie leere Verzeichnisse oder Verzeichnisse mit einer kleinen Anzahl von Dateien enthalten. Diese Verzeichnisse werden niemals entfernt und nicht besiedelt.
Wenn Sie leere oder spärlich besiedelte Verzeichnisse verhindern möchten, müssen Sie eine Wartungsaufgabe gegen das blobStoreRoot -Verzeichnis ausführen. Diese Wartungsaufgabe muss nach leeren oder unvollständigen Verzeichnissen suchen und die Methode SetCurrentBlobdir aufrufen, die den leeren blobPath weitergeben.
Für Ihre Anwendung werden Sie möglicherweise selten eine große Anzahl von Blob -Dateien entfernen. Wenn dies der Fall ist, kann dieses Problem ignoriert werden.
Es gibt zwei Methoden zum Testen scalable-blob-store :
os.tmpdir() -Verzeichnis verwendet. Geben Sie nach dem Klonen scalable-blob-store Folgendes in Ihre Konsole ein:
npm install
npm test
Durch das Ausführen der Test-Fs.js-Datei wird ein ~/blobs -Verzeichnis in Ihrem temporären Verzeichnis erstellt und es dann rekursiv mit vielen Blobs füllen.
Die in der test-fs.js Datei konfigurierten Standardoptionen sind:
const opts = {
blobStoreRoot : os . tmpdir ( ) + '/blobs' ,
idFunction : cuid ,
dirDepth : 3 ,
dirWidth : 1000 ,
} ;
const repeat = 10000 ;Ändern Sie die Optionen, wenn Sie unterschiedliche Ergebnisse sehen möchten.
Geben Sie nach dem Klonen scalable-blob-store Folgendes in Ihre Konsole ein:
npm install
node ./tests/test-fs.js
Überprüfen Sie nach Abschluss das Verzeichnis /tmp/blobs . Ich schlage vor, mit dem Befehl Baum zu verwenden, der Ihnen eine Zusammenfassung der Verzeichnisse und Dateien im Zielverzeichnis gibt.
tree ~ /blobs
tree -d ~ /blobs
Ich, Grant Carthew, bin ein Technologe aus Queensland, Australien. Ich arbeite in einer Reihe von persönlichen Projekten an Code und wenn es nötig ist, baue ich meine eigenen Pakete auf.
Dieses Projekt existiert, weil ich einen lokalen Blob -Store brauchte, der skalieren könnte.
Alles, was ich in Open Source mache, wird in meiner eigenen Zeit und als Beitrag zur Open -Source -Community gemacht.
Wenn Sie meine Projekte verwenden und mich danken oder mich unterstützen möchten, klicken Sie bitte auf den Link Patreon unten.
Siehe meine anderen Projekte auf NPM.
git checkout -b my-new-featuregit commit -am 'Add some feature'git push origin my-new-featurenode-uuid durch uuid .ES5 Build-Code zu verwenden. NodeJS -Motoranforderungen entfernt.return null .return null nach Auflösung/Ablehnung von Aufrufen, um Bluebird-Warnungen zu verhindern.es5dist für ältere Versionen des Knotens hinzugefügt. Pakete aktualisiert.MIT