[Nodejs] módulo incorporado de nodejs (medio)

inserte la descripción de la imagen aquí

1. Ruta del módulo de procesamiento de Road King


1.1 Resumen del módulo

En nodejs, la ruta es un módulo que se usa con frecuencia, pero la gente lo ama y lo odia. En parte porque la documentación no es lo suficientemente clara, en parte por las diferencias de plataforma de la interfaz. Clasifique la interfaz de ruta de acuerdo con su propósito, y después de una cuidadosa consideración, no será tan confuso.

1.2 Obtener ruta/nombre de archivo/extensión

  • Obtenga la ruta: ruta.dirname (ruta del archivo)
  • Obtenga el nombre del archivo: path.basename(filepath)
  • Obtenga la extensión: ruta.extname (ruta del archivo)

(1) Obtenga la ruta donde se encuentra,
los ejemplos son los siguientes:

var path = require('path');
var filepath = '/tmp/demo/js/test.js';

// 输出:/tmp/demo/js
console.log( path.dirname(filepath) );

(2) Obtener el nombre del archivo
Estrictamente hablando, path.basename(filepath) es solo la última parte de la ruta de salida y no determina si es un nombre de archivo. Pero la mayoría de las veces, podemos usarlo como un método simple de "obtener nombre de archivo".

var path = require('path');

// 输出:test.js
console.log( path.basename('/tmp/demo/js/test.js') );

// 输出:test
console.log( path.basename('/tmp/demo/js/test/') );

// 输出:test
console.log( path.basename('/tmp/demo/js/test') );

¿Qué sucede si solo desea obtener el nombre del archivo, pero no la extensión del archivo? Puede utilizar el segundo parámetro.

// 输出:test
console.log( path.basename('/tmp/demo/js/test.js', '.js') );

(3) Obtenga la extensión del archivo.
Un ejemplo simple es el siguiente:

var path = require('path');
var filepath = '/tmp/demo/js/test.js';

// 输出:.js
console.log( path.extname(filepath) );

Una regla más detallada es la siguiente: (asumiendo path.basename(filepath) === B )

  • Intersección desde el último de B hasta el último carácter.
  • Si .no existe en B, o el primer carácter de B es ., devuelve una cadena vacía.

Mire directamente el ejemplo del documento oficial.

path.extname('index.html')
// returns '.html'

path.extname('index.coffee.md')
// returns '.md'

path.extname('index.')
// returns '.'

path.extname('index')
// returns ''

path.extname('.index')
// returns ''

1.3 Combinación de rutas

path.join([...paths])
path.resolve([...paths])

(1) ruta absoluta generada por path.resolve()
Formato de sintaxis:

path.resolve([...myPaths])

explicar:

  • Resuelve una secuencia de rutas o fragmentos de rutas como rutas absolutas.
  • La ruta devuelta se procesa de derecha a izquierda, y cada myPath subsiguiente se analiza a su vez hasta que se construye una ruta absoluta completa.

你可以想象现在你在shell下面,从左到右运行一遍cd path命令,最终获取的绝对路径/文件名,就是这个接口所返回的结果了。
Ejemplo de código:

const path = require('path');

let arr1 = ['/foo1/foo2', 'dselegent', 'foo3'];
let result1 = path.resolve(...arr1);
console.log(result1); // 打印结果:/foo1/foo2/dselegent/foo3

let arr2 = ['/foo1/foo2', '/dselegent', 'foo3'];
let result2 = path.resolve(...arr2);
console.log(result2); // 打印结果:/dselegent/foo3
const path = require('path');

// 假设当前工作路径是 /Users/a/Documents/git-code/nodejs-learning-guide/examples/2016.11.08-node-path

// 输出 /Users/a/Documents/git-code/nodejs-learning-guide/examples/2016.11.08-node-path
console.log( path.resolve('') )

// 输出 /Users/a/Documents/git-code/nodejs-learning-guide/examples/2016.11.08-node-path
console.log( path.resolve('.') )

// 输出 /foo/bar/baz
console.log( path.resolve('/foo/bar', './baz') );

// 输出 /foo/bar/baz
console.log( path.resolve('/foo/bar', './baz/') );

// 输出 /tmp/file
console.log( path.resolve('/foo/bar', '/tmp/file/') );

// 输出 /Users/a/Documents/git-code/nodejs-learning-guide/examples/2016.11.08-node-path/www/js/mod.js
console.log( path.resolve('www', 'js/upload', '../mod.js') );

(2) path.join() une múltiples caminos
Si unimos manualmente los caminos, es fácil cometer errores. En este momento, puede usar el método path.join() para unir las rutas.

Formato de gramática:

path.join([...paths]);

Explicación: concatena todos los fragmentos de ruta proporcionados usando el delimitador específico de la plataforma como delimitador y luego normaliza la ruta resultante.

Ejemplo de código:

const path = require('path');

const result1 = path.join(__dirname, './app.js');
console.log(result1); // 返回:/Users/smyhvae/dselegent/app.js

const result2 = path.join('/foo1', 'foo2', './foo3');
console.log(result2); // 返回:/foo1/foo2/foo3

const result3 = path.join('/foo1', 'foo2', '/foo3');
console.log(result3); // 返回:/foo1/foo2/foo3

(3) La diferencia path.resolvedepath.join
path.resolve y path.joinson ambos métodos bajo el módulo principal de ruta, que se utilizan para empalmar rutas.

se puede concatenar en una ruta completa.

const path = require("path");

var dirname = '/User/Desktop';
var basename = 'abc.txt';

path.join(dirname, basename);  // /User/Desktop/abc.txt

path.resolve(dirname, basename);  // /User/Desktop/abc.txt

Si dirname comienza con ./, .../, sin /, entonces resolve encontrará el directorio raíz debajo del disco

const path = require("path");
 
var dirname = '../User/Desktop';
var basename = 'abc.txt';
 
path.join(dirname, basename);  // ../User/Desktop/abc.txt
 
path.resolve(dirname, basename);  // /Users/Desktop/node/User/Desktop/abc.txt

Si el nombre base comienza con /, entonces resolve devolverá directamente el nombre base

const path = require("path");
 
var dirname = '/User/Desktop';
var basename = '/abc.txt';
 
path.join(dirname, basename);  // /User/Desktop/abc.txt
 
path.resolve(dirname, basename);  // /abc.txt

1.4 Varios caminos comunes

__dirname: Esta es una constante, lo que significa: el directorio completo donde se encuentra el archivo de ejecución actual.
__filename: Esta es una constante. Indica: el directorio completo + nombre de archivo del archivo actualmente ejecutado.
process.cwd: obtiene el nombre del directorio cuando el comando Node se ejecuta actualmente.
Ejemplo de código:

console.log(__dirname);
console.log(__filename);
console.log(process.cwd());

resultado de la operación:

$ node app.js

/Users/smyhvae/dselegent
/Users/smyhvae/dselegent/app.js
/Users/smyhvae/dselegent

2. Módulo de operación de archivo local fs


La diferencia entre síncrono y asíncrono en Node.js
El módulo fs tiene dos formas de síncrono y asíncrono para casi todas las operaciones en archivos. Por ejemplo: readFile()y readFileSync().

la diferencia:

  • Las llamadas síncronas bloquean la ejecución del código, las llamadas asíncronas no.
  • La llamada asincrónica enviará la tarea de lectura a la cola de tareas y no devolverá la llamada hasta que se complete la ejecución de la tarea.
  • Manejo de excepciones: la sincronización debe usar el método try catch, la asincronía puede pasar el primer parámetro de la función de devolución de llamada. ★★★★★

2.1 Lectura de archivos

lectura sincronizada

var fs = require('fs');
var data;

try{
    
    
    data = fs.readFileSync('./fileForRead.txt', 'utf8');
    console.log('文件内容: ' + data);
}catch(err){
    
    
    console.error('读取文件出错: ' + err.message);
}

La salida es la siguiente:

/usr/local/bin/node readFileSync.js
文件内容: hello world

lectura asíncrona

var fs = require('fs');

fs.readFile('./fileForRead.txt', 'utf8', function(err, data){
    
    
    if(err){
    
    
        return console.error('读取文件出错: ' + err.message);
    }
    console.log('文件内容: ' + data);
});

La salida es la siguiente

/usr/local/bin/node readFile.js
文件内容: hello world

fs/promises 从 Node.js 14 开始可用 从 Node.js 14 开始,fs 模块提供了两种使用基于 promises 的文件系统的方法。这些 promises 可以通过 require('fs').promises 或 require('fs/promises') 获得。

import {
    
     readFile } from 'fs/promises';

try {
    
    
  const contents = await readFile(filePath, {
    
     encoding: 'utf8' });
  console.log(contents);
} catch (err) {
    
    
  console.error(err.message);
}

2.2 Escritura de archivos

Observaciones: El siguiente código, si el archivo no existe, crea el archivo, si el archivo existe, sobrescribe el contenido del archivo;

escribir asincrónicamente

var fs = require('fs');

fs.writeFile('./fileForWrite.txt', 'hello world', 'utf8', function(err){
    
    
    if(err) throw err;
    console.log('文件写入成功');
});

escribir sincrónicamente

var fs = require('fs');

try{
    
    
    fs.writeFileSync('./fileForWrite1.txt', 'hello world', 'utf8');
    console.log('文件写入成功');
}catch(err){
    
    
    throw err;
}

promesas

import {
    
     writeFile } from 'fs/promises';

try {
    
    
  const contents = await writeFile('message.txt', 'hello world', {
    
     encoding: 'utf8' });
  console.log(contents);
} catch (err) {
    
    
  // When a request is aborted - err is an AbortError
  console.error(err);
}

2.3 Si el archivo existe

fs.exists()Ya está en deprecatedel estado, y ahora puede juzgar si el archivo existe a través del siguiente código.

versión asíncrona

const fs = require('fs')

//检查文件是否存在于当前目录中
fs.access('package.json', fs.constants.F_OK, err => {
    
    
    if(err) {
    
    
        console.log('package.json不存在于当前目录中')
        return
    }
    console.log('package.json存在于当前目录中')
})

fs.access('index.js', fs.constants.F_OK, err => {
    
    
    if(err) {
    
    
        console.log('index.js不存在于当前目录中')
        return
    }
    console.log('index.js存在于当前目录中')
})

fs.access()Además de juzgar si el archivo existe (modo predeterminado), también se puede usar para juzgar los permisos del archivo.

Observaciones: fs.constants.F_OKno se pueden obtener constantes (nodo v6.1, bajo mac 10.11.4, fs.constantsundefined)

Sincronizar

import {
    
     accessSync, constants } from 'fs';

try {
    
    
  accessSync('etc/passwd', constants.R_OK );
  console.log('can read');
} catch (err) {
    
    
  console.error('no access!');
}

promesas

import {
    
     access, constants } from 'node:fs/promises';

try {
    
    
  await access('/etc/passwd', constants.R_OK);
  console.log('can access');
} catch {
    
    
  console.error('cannot access');
}

2.4 Eliminar archivos

versión asíncrona

var fs = require('fs');

fs.unlink('./fileForUnlink.txt', function(err){
    
    
    if(err) throw err;
    console.log('文件删除成功');
});

versión de sincronización

import {
    
     unlinkSync } from 'fs';

try {
    
    
  unlinkSync('/tmp/hello');
  console.log('successfully deleted /tmp/hello');
} catch (err) {
    
    
  // handle the error
}

promesas

import { unlink } from 'fs/promises';

try {
  await unlink('/tmp/hello');
  console.log('successfully deleted /tmp/hello');
} catch (err) {
  // handle the error
}

2.5 Crear directorio

Versión asíncrona (arroja un error si el directorio ya existe)

// fs.mkdir(path[, mode], callback)
var fs = require('fs');

fs.mkdir('sub', function(err){
    
    
    if(err) throw err;
    console.log('创建目录成功');
});

versión de sincronización

// fs.mkdirSync(path[, mode])
var fs = require('fs');

try{
    
    
    fs.mkdirSync('hello');
    console.log('创建目录成功');
}catch(e){
    
    
    throw e;
}

promesas

import {
    
     mkdir } from 'fs/promises';

try {
    
    
  const createDir = await mkdir(projectFolder, {
    
     recursive: true });
  console.log(`created ${
      
      createDir}`);
} catch (err) {
    
    
  console.error(err.message);
}

2.6 Recorrer directorios

Versión síncrona, nota: fs.readdirSync() solo leerá una capa, por lo que es necesario determinar si el tipo de archivo es un directorio y, de ser así, realizar un recorrido recursivo.

// fs.readdirSync(path[, options])
var fs = require('fs');
var path = require('path');
var getFilesInDir = function(dir){
    
    
    var results = [ path.resolve(dir) ];
    var files = fs.readdirSync(dir, 'utf8');
    files.forEach(function(file){
    
    
        file = path.resolve(dir, file);
        var stats = fs.statSync(file);
        if(stats.isFile()){
    
    
            results.push(file);
        }else if(stats.isDirectory()){
    
    
            results = results.concat( getFilesInDir(file) );
        }
    });
    return results;
};
var files = getFilesInDir('../');
console.log(files);

2.7 Leer directorio

import {
    
     readdir } from 'fs/promises';

try {
    
    
  const files = await readdir(path);
  for (const file of files)
    console.log(file);
} catch (err) {
    
    
  console.error(err);
}

2.8 Eliminar directorio

// 删除目录(前提没有文件在里面)
fs.rmdir('./avatar', err => {
    
    
  if (err && err.code === 'ENOENT') {
    
    
    console.log('目录不存在');
  }
});

2.9 Eliminar todo el directorio

//1
const fs = require("fs")
fs.("./avatar",(err,data)=>{
    
    
    // console.log(data)
    data.forEach(item=>{
    
    
        fs.unlinkSync(`./avatar/${
      
      item}`)
    })

    fs.rmdir("./avatar",(err)=>{
    
    
        console.log(err)
    })
})

//2
const fs = require('fs')
fs.readdir("./avatar").then(async (data)=>{
    
    
    let arr = []
    data.forEach(item=>{
    
    
        arr.push(fs.unlink(`./avatar/${
      
      item}`))
    })
    await Promise.all(arr)
    fs.rmdir("./avatar")
})

//3
const fs = require('fs').promises;
fs.readdir('./image2').then(async data => {
    
    
  await Promise.all(data.map(item => fs.unlink(`./image2/${
      
      item}`)));
  await fs.rmdir('./image2');
});

2.10 Cambio de nombre de archivo

versión asíncrona

// fs.rename(oldPath, newPath, callback)
var fs = require('fs');

fs.rename('./hello', './world', function(err){
    
    
    if(err) throw err;
    console.log('重命名成功');
});

versión de sincronización

// fs.renameSync(oldPath, newPath)
var fs = require('fs');

fs.renameSync('./world', './hello');
promises

import {
    
     rename } from 'fs/promises';

try {
    
    
  await rename('./world', './hello');
  console.log(`rename`);
} catch (err) {
    
    
  console.error(err.message);
}

2.11 Obtener el estado del archivo

(1) Asíncrono: fs.stat(ruta, devolución de llamada): ruta es una cadena que representa la ruta, y la devolución de llamada recibe dos parámetros (err, estadísticas), donde estadísticas es una instancia de fs.stats;

(2) Sincronización: fs.statSync(ruta) solo recibe una variable de ruta, y fs.statSync(ruta) es en realidad una instancia de fs.stats;

método

  • stats.isFile() – si es un archivo
  • stats.isDirectory() – si el directorio
// Node.js program to demonstrate the 
// fs.statSync() method 
  
// Import the filesystem module 
const fs = require('fs'); 
  
// Getting information for a file 
statsObj = fs.statSync("test_file.txt"); 
  
console.log(statsObj);  
console.log("Path is file:", statsObj.isFile()); 
console.log("Path is directory:", statsObj.isDirectory()); 
  
// Getting information for a directory 
statsObj = fs.statSync("test_directory"); 
  
console.log(statsObj); 
console.log("Path is file:", statsObj.isFile()); 
console.log("Path is directory:", statsObj.isDirectory());

producción:

Stats {
    
    
  dev:3229478529,
  mode:33206,
  nlink:1,
  uid:0,
  gid:0,
  rdev:0,
  blksize:4096,
  ino:1970324837039946,
  size:0,
  blocks:0,
  atimeMs:1582306776282,
  mtimeMs:1582482953967,
  ctimeMs:1582482953968.2532,
  birthtimeMs:1582306776282.142,
  atime:2020-02-21T17:39:36.282Z,
  mtime:2020-02-23T18:35:53.967Z,
  ctime:2020-02-23T18:35:53.968Z,
  birthtime:2020-02-21T17:39:36.282Z
}
Path is file:true
Path is directory:false
Stats {
    
    
  dev:3229478529,
  mode:16822,
  nlink:1,
  uid:0,
  gid:0,
  rdev:0,
  blksize:4096,
  ino:562949953486669,
  size:0,
  blocks:0,
  atimeMs:1582482965037.8445,
  mtimeMs:1581074249467.7114,
  ctimeMs:1582482964979.8303,
  birthtimeMs:1582306776288.1958,
  atime:2020-02-23T18:36:05.038Z,
  mtime:2020-02-07T11:17:29.468Z,
  ctime:2020-02-23T18:36:04.980Z,
  birthtime:2020-02-21T17:39:36.288Z
}
Path is file:false
Path is directory:true

2.12 Agregar contenido del archivo

fs.appendFile(file, data[, options], callback)

  • archivo: puede ser una ruta de archivo o un identificador de archivo. (¿Puede ser también un amortiguador?)
  • data: el contenido a anexar. cadena o búfer.
  • opciones
    • codificación: codificación, el valor predeterminado es utf8
    • modo: el valor predeterminado es 0o666
  • bandera: el valor predeterminado es un

Nota: si el archivo es un identificador de archivo, entonces

  • El archivo debe estar abierto antes de comenzar a agregar datos.
  • El archivo debe cerrarse manualmente.
var fs = require('fs');
fs.appendFile('./extra/fileForAppend.txt', 'hello', 'utf8', function(err){
    
    
    if(err) throw err;
    console.log('append成功');
});

3. Eventos del módulo del mecanismo de eventos


Node.js tiene múltiples eventos integrados. Podemos enlazar y escuchar eventos introduciendo eventsmódulos e instanciando clases, como se muestra en el siguiente ejemplo:EventEmitter

// 引入 events 模块
var EventEmitter = require('events');
// 创建 eventEmitter 对象
var event = new EventEmitter();

El siguiente programa vincula los controladores de eventos:

// 绑定事件及事件的处理程序
eventEmitter.on('eventName', eventHandler);

Podemos desencadenar eventos programáticamente:

// 触发事件
eventEmitter.emit('eventName');

EventEmitterCada evento de se compone de un nombre de evento y varios parámetros.El nombre del evento es una cadena, que suele expresar cierta semántica. Para cada evento, EventEmitterse admiten varios detectores de eventos.

Cuando se activa un evento, los detectores de eventos registrados en este evento se llaman a su vez y los parámetros del evento se pasan como parámetros de la función de devolución de llamada.

Expliquemos este proceso con el siguiente ejemplo:

// 引入 events 模块
var EventEmitter = require('events');
// 创建 eventEmitter 对象
var event = new EventEmitter();
event.on('someEvent', function(arg1, arg2) {
    
     
    console.log('listener1', arg1, arg2); 
}); 
event.on('someEvent', function(arg1, arg2) {
    
     
    console.log('listener2', arg1, arg2); 
}); 
event.emit('someEvent', 'arg1 参数', 'arg2 参数'); 

Ejecute el código anterior, el resultado de la operación es el siguiente:

$ node event.js 
listener1 arg1 参数 arg2 参数
listener2 arg1 参数 arg2 参数

En el ejemplo anterior, se registran dos detectores de eventos eventpara el evento y luego se activa el evento.someEventsomeEvent

En el resultado de la ejecución, puede ver que las dos funciones de devolución de llamada del detector de eventos se llaman sucesivamente. Este es EventEmitterel uso más simple.

EventEmitterSe proporcionan varias propiedades, como ony emit. onLas funciones se utilizan para vincular funciones de eventos, emitlas propiedades se utilizan para desencadenar un evento.

Supongo que te gusta

Origin blog.csdn.net/weixin_43094619/article/details/131910037
Recomendado
Clasificación