Una tienda de blob del sistema de archivos que está diseñado para evitar conflictos cuando se usa con un sistema de archivos distribuido o una red de área de almacenamiento.
Estrella en GitHub / NPM y busque actualizaciones.
Nota: requiere Node.js v12 o posterior.
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.Vea los archivos de ejemplo de inicio rápido para obtener más detalle:
Después de investigar el almacenamiento de archivos de usuario o el almacenamiento de blob, para una aplicación web en la que estaba trabajando, descubrí que la solución más común utilizada por los desarrolladores web es almacenar archivos utilizando un proveedor de servicios en la nube. Después de crear una cuenta con proveedores como Amazon S3, Google Cloud Storage o Azure Storage, simplemente guardan todos sus archivos de aplicaciones y blobs allí.
Investigué el precio del almacenamiento en la nube y decidí que quería una versión local gratuita que escalaría si fuera necesario.
Observé una serie de soluciones existentes, como Filest Arapking, pero no estaba contento con la escalabilidad de estas soluciones. La mayoría solo están diseñados para un solo servidor y causarían conflictos de escritura si un sistema de archivos distribuido, un sistema de archivos de clúster como Glusterfs o una red de área de almacenamiento se usaron como sistema de archivos de backend.
En un largo viaje en automóvil, estaba pensando en una solución para mi almacenamiento de blob y se me ocurrió scalable-blob-store .
Para lograr la escalabilidad en un sistema de archivos distribuido o replicado, scalable-blob-store no utiliza archivos de índice u otras bases de datos para administrar los archivos en el sistema de disco o almacenamiento. En su lugar, el sistema de archivos en sí se utiliza para encontrar la última ruta de almacenamiento basada en el atributo birthtime de los sistemas de archivos (la fecha de creación de directorio).
Una vez que se ha determinado la última ruta, se cuenta el número de archivos dentro del directorio para garantizar que permanezca bajo el valor configurado. Esto es para evitar problemas de rendimiento del disco cuando se almacenan números muy grandes de archivos dentro de un solo directorio. Si el número de elementos dentro de un directorio se vuelve demasiado grande, se determina una nueva ruta de almacenamiento.
Debido a que no hay bases de datos utilizadas para administrar los archivos en la ruta raíz, depende de usted mantener el valor y metadatos blobPath devueltos sobre los archivos almacenados en su propia base de datos.
La razón por la que scalable-blob-store se debe a los nombres de los directorios y archivos dentro de su sistema de archivos. Cada directorio y archivo guardado en el disco está nombrado por una ID única generada basada en un funcido definido por el usuario. Puede usar cualquier generador de identificación único como ULID, CUID, UUID V4 o MongoDBS ObjectIDs solo por nombrar algunos. Echa un vistazo a mi increíble repositorio de identificación único para obtener más ejemplos. Fusionar directorios entre servidores o discos nunca debe causar colisiones de nombres de archivo.
Si un sistema de archivos replicado o de clúster está en uso, el único conflicto que puede ocurrir es cuando un servidor está leyendo un archivo mientras otro elimina el mismo archivo. scalable-blob-store no intenta gestionar este conflicto, sin embargo, aumentará la excepción.
A continuación se presentan ejemplos de la estructura del directorio creada por scalable-blob-store .
Ejemplo con directorio CUID y nombres de archivo:
b lobs c ij50xia200pzzph3we9r62bi // ← Directory File ↓
b lobs c ij50xia300q1zph3m4df4ypz . . c ij50xiae00qgzph3i0ms0l2wEjemplo con directorio UUID y nombres de archivo:
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 admite opciones de configuración para brindarle control sobre el directorio y los ID de archivo utilizados, la profundidad de la estructura del directorio y el ancho de los directorios. Las opciones predeterminadas dan 3 directorios profundos que contienen 1000 elementos que dan un almacenamiento total de mil millones de archivos dentro de la estructura del directorio.
Otros puntos de interés operativos:
dirWidth , se crea el siguiente directorio.dirWidth , se crea el próximo directorio principal.dirWidth , se ignora el valor dirWidth . Escribir
En mi computadora portátil con un disco M.2 SSD, ejecutar el script Test-Fs.js produce los siguientes resultados:
====================================================================================================
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.
====================================================================================================
Leer
El rendimiento de lectura estará cerca, si no lo mismo, como la velocidad del disco.
Todos los métodos blobstore dentro de scalable-blob-store devuelven una promesa. Esto es perfecto para usar con las características del lenguaje async/esperanza.
| API | Tipo | Devolución |
|---|---|---|
| Nueva blobstore (opciones) | Constructor | instancia de blobstore |
| blobstore.blobstoreroot | Leer solo propiedad | String |
| blobstore.idfunction | Leer solo propiedad | Function |
| blobstore.dirdepth | Leer solo propiedad | Number |
| blobstore.dirwidth | Leer solo propiedad | Number |
| blobstore.getCurrentBlobDir () | Método | Promise<String> |
| blobstore.setCurrentBlobDir (blobdir) | Método | Promise<undefined> |
| blobstore.createwriteReam () | Método | Promise<Object> |
| blobstore.write (datos, writeOptions) | Método | Promise<String> |
| blobstore.append (blobpath, datos, apéndectaciones) | Método | Promise<undefined> |
| blobstore.copy (blobpath, banderas) | Método | Promise<String> |
| blobstore.createReadstream (Blobpath) | Método | Promise<ReadStream> |
| blobstore.read (blobpath, readoptions) | Método | Promise<data> |
| blobstore.open (blobpath, banderas, modo) | Método | Promise<FileHandle> |
| Blobstore.RealPath (Blobpath, RealPathOptions) | Método | Promise<String> |
| blobstore.stat (Blobpath) | Método | Promise<Stats> |
| blobstore.exists (Blobpath) | Método | Promise<Boolean> |
| blobstore.remove (Blobpath) | Método | Promise<undefined> |
new BlobStore(options)Tipo: función del constructor.
Parámetro: options como Object .
Devuelve : un nuevo objeto BlobStore que se utilizará para almacenar datos.
Descripción:
Puede llamar new BlobStore(options) varias veces para crear más de una tienda BLOB.
Las opciones se pasan a la función del constructor como un object JavaScript.
| Llave | Descripción | Valores predeterminados |
|---|---|---|
blobStoreRoot | Directorio de raíz para almacenar blobs | Requerido |
idFunction | Cualquier función de identificación que devuelva una cadena de identificación única | Requerido |
dirDepth | Cuán profundo quieres los directorios debajo de la raíz | 3 |
dirWidth | El número máximo de archivos o directorios en un directorio | 1000 |
Ejemplo:
// 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 ) ;Creación de múltiples tiendas 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 ) ;blobStoreRootTipo: Leer solo propiedad.
Devuelve: una String que coincide con sus options.blobStoreRoot BLOBSTOREROOT Valor.
Descripción:
Esta es una propiedad de conveniencia para permitirle pasar el objeto blobstore a un submódulo y aún tener acceso a las propiedades configuradas.
Ejemplo:
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 optionsidFunctionTipo: Leer solo propiedad.
Devuelve: La función de identificación única que configuró en el valor de options.idFunction .
Descripción:
Esta es una propiedad de conveniencia para permitirle pasar el objeto blobstore a un submódulo y aún tener acceso a las propiedades configuradas.
Ejemplo:
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.dirDepthTipo: Leer solo propiedad.
Devuelve: un Number que coincide con sus options.dirDepth .
Descripción:
Esta es una propiedad de conveniencia para permitirle pasar el objeto blobstore a un submódulo y aún tener acceso a las propiedades configuradas.
Ejemplo:
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 optionsdirWidthTipo: Leer solo propiedad.
Devuelve: un Number que coincide con sus options.dirWidth Valor de urbanismo.
Descripción:
Esta es una propiedad de conveniencia para permitirle pasar el objeto blobstore a un submódulo y aún tener acceso a las propiedades configuradas.
Ejemplo:
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()Tipo: Método.
Devuelve: una Promise que se resuelve a una String que es el directorio de creación de blob activo actual.
Descripción:
El BlobStore usa esta función internamente para determinar el directorio donde el próximo archivo blob se guardará en el disco.
Si alguna vez necesita almacenar un archivo Blob fuera de BlobStore , puede usar este método para localizar el lugar correcto para colocar su archivo.
Ejemplo:
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)Tipo: Método.
Parámetros: blobDir como una String .
blobStoreRoot . Devoluciones: una Promise que resuelve a undefined .
Descripción:
Esta función se puede usar para guiar el BlobStore para guardar nuevos archivos blob en un blobPath deseado.
Un problema con scalable-blob-store es que si elimina muchos archivos blob, los directorios en los que se ubicaron los archivos no se eliminarán. Puede eliminar los directorios usted mismo o repoblarlos con nuevos archivos Blob configurando el directorio BLOB activo actual.
Esta función se agregó para permitir a los consumidores de este módulo trabajar en los directorios de blob vacíos.
Ejemplo:
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()Tipo: Método.
Devuelve : Una Promise que resuelve a un Object que contiene la ruta del niño al archivo dentro de la raíz de la tienda blob y una transmisión por escrito.
Descripción:
Aquí hay un Exampe del objeto devuelto usando UUID como 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
} Use el writeStream para guardar su blob o archivo. El blobPath debe guardar en su base de datos para el acceso futuro.
Ejemplo:
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)Tipo: Método.
Parámetro: data como String , Buffer , TypedArray o DataView .
Parámetro: writeOptions como un Object .
writeOptions admite una propiedad de codificación, modo y bandera. Devuelve: Una Promise que se resuelve a una String .
blobPath que necesita comprometerse con su base de datos.Descripción:
Si tiene datos simples en la memoria en lugar de un flujo de datos, puede usar este método para almacenar los datos en un archivo blob.
Ejemplo:
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)Tipo: Método.
Parámetro: blobPath como una String .
blobPath de su base de datos de aplicaciones. Parámetro: data como una String o Buffer .
Parámetro: appendOptions como un Object .
appendOptions admite una propiedad de codificación, modo y bandera. Devoluciones: una Promise que se resuelve a un undefined .
Descripción:
Use este método para agregar datos simples en la memoria al final del archivo BLOB.
Ejemplo:
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)Tipo: Método.
Parámetro: blobPath como una String .
blobPath de su base de datos de aplicaciones. Parámetro: flags como un Number .
Devuelve: Una Promise que se resuelve a una String .
blobPath para el archivo BLOB copiado.Descripción:
Use este método para crear una copia de un archivo blob existente.
Ejemplo:
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)Tipo: Método.
Parámetro: blobPath como una String .
blobPath de su base de datos de aplicaciones. Devuelve : una Promise que se resuelve a un ReadStream .
Descripción:
Crea una transmisión legible para el archivo BLOB ubicado en el blobPath .
Ejemplo:
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)Tipo: Método.
Parámetro: blobPath como una String .
blobPath de su base de datos de aplicaciones. Parámetro: readOptions como Object .
Devuelve: Una Promise que resuelve el contenido del archivo blob.
scalable-blob-store establece las readOptions.encoding Valor de codificación a 'UTF8' de forma predeterminada.Descripción:
Use este método para leer el contenido de un pequeño archivo BLOB en la memoria.
Ejemplo:
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)Tipo: Método.
Parámetro: blobPath como una String .
blobPath de su base de datos de aplicaciones. Parámetro: flags como una String o Number .
Devuelve: Una Promise que se resuelve a un objeto FileHandle.
Descripción:
Este es un método más avanzado que le permite llevar a cabo muchas operaciones de archivo contra el archivo blob.
Ejemplo:
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)Tipo: Método.
Parámetro: blobPath como una String .
blobPath de su base de datos de aplicaciones. Parámetro: realPathOptions como una String u Object .
Devuelve: Una Promise que se resuelve a una String .
Descripción:
Use este método para localizar un archivo blob en el sistema de archivos. Este método no debería ser realmente necesario porque puede determinar la ruta completa del archivo BLOB. Simplemente concatene el blobstoreroot y los valores de blobpath.
Ejemplo:
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)Tipo: Método.
Parámetro: blobPath como una String .
Devuelve: un Object STATS.
Descripción:
En lugar de analizar el objeto stats del sistema de archivos, scalable-blob-store devuelve el objeto stats RAW.
Se pueden encontrar más detalles de la clase de estadísticas en Wikipedia.
Ejemplo:
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)Tipo: Método.
Parámetro: blobPath como una String .
Devoluciones: Boolean
true Si el archivo existe, de lo contrario false .Descripción:
Use este método para una prueba simple de existencia de archivo blob.
Ejemplo:
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)Tipo: Método.
Parámetro: blobPath como una String .
Devuelve : undefined si nada salió mal o el archivo no existía.
Descripción:
Use este método para eliminar un archivo blob. Este método no se puede usar para eliminar directorios.
Ejemplo:
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 ( ) ; Hay un problema menor en scalable-blob-store . Si se agregan una gran cantidad de archivos blob y luego se eliminan de la tienda BLOB, puede tener directorios o directorios vacíos con una pequeña cantidad de archivos en ellos. Estos directorios nunca se eliminarán y no se poblarán.
Si desea evitar directorios vacíos o escasamente poblados, deberá ejecutar una tarea de mantenimiento contra el directorio blobStoreRoot . Esta tarea de mantenimiento deberá buscar directorios vacíos o incompletos y llamar al método setCurrentBlobDir que pasa en el blobPath vacío.
Para su aplicación, puede encontrar que rara vez elimina grandes cantidades de archivos blob. Si este es el caso, este problema se puede ignorar.
Hay dos métodos para probar scalable-blob-store :
os.tmpdir() local. Después de clonar scalable-blob-store , escriba lo siguiente en su consola:
npm install
npm test
Ejecutar el archivo Test-Fs.js creará un directorio ~/blobs en su directorio temporal y luego lo llenará recursivamente con muchos blobs.
Las opciones predeterminadas configuradas en el archivo test-fs.js son:
const opts = {
blobStoreRoot : os . tmpdir ( ) + '/blobs' ,
idFunction : cuid ,
dirDepth : 3 ,
dirWidth : 1000 ,
} ;
const repeat = 10000 ;Cambie las opciones si desea ver resultados diferentes.
Después de clonar scalable-blob-store , escriba lo siguiente en su consola:
npm install
node ./tests/test-fs.js
Una vez completado, inspeccione el directorio /tmp/blobs . Sugiero usar el comando de árbol que le brinda un resumen de directorios y archivos dentro del directorio de destino.
tree ~ /blobs
tree -d ~ /blobs
Yo, Grant Carthew, soy tecnólogo de Queensland, Australia. Trabajo en código en una serie de proyectos personales y cuando surge la necesidad, construyo mis propios paquetes.
Este proyecto existe porque necesitaba una tienda de blob local que pudiera escalar.
Todo lo que hago en código abierto se hace en mi propio tiempo y como contribución a la comunidad de código abierto.
Si está utilizando mis proyectos y desea agradecerme o apoyarme, haga clic en el enlace de Patreon a continuación.
Vea mis otros proyectos en NPM.
git checkout -b my-new-featuregit commit -am 'Add some feature'git push origin my-new-featurenode-uuid reemplazado con uuid .ES5 . Requisitos de motor NodeJs eliminados.return null .return null después de resolver/rechazar llamadas para evitar advertencias de pájaros azules.es5dist para versiones anteriores de Node. Paquetes actualizados.MIT