Leer y escribir archivos JSON con Node.js

Una de las mejores formas de intercambiar información entre aplicaciones escritas en diferentes lenguajes es usar el formato JSON (Notación de objetos de JavaScript). Gracias...

Una de las mejores formas de intercambiar información entre aplicaciones escritas en diferentes idiomas es usar el formato JSON (Notación de objetos de JavaScript). Gracias a su uniformidad y simplicidad, JSON ha reemplazado casi por completo a XML como el formato estándar de intercambio de datos en software, particularmente en servicios web.

Dado el amplio uso de JSON en las aplicaciones de software, y especialmente en las aplicaciones basadas en JavaScript, es importante saber cómo leer y escribir datos JSON en un archivo en Node.js. En este artículo explicaremos cómo realizar estas funciones.

Leer un archivo JSON

Primero veamos como podemos leer un archivo que ya ha sido creado. Pero antes de hacer eso, necesitamos crear el archivo. Abra una nueva ventana en su editor de texto favorito y agréguele el siguiente texto:

1
2
3
4
5
6
7
{ 
    "name": "Sara",
    "age": 23,
    "gender": "Female",
    "department": "History",
    "car": "Honda"
}

Ahora guarde este archivo como "student.json" en el directorio de su proyecto.

Para leer los datos JSON del archivo, podemos usar el módulo Node.js fs. Hay dos funciones disponibles en este módulo que podemos usar para leer archivos del sistema de archivos: readFile y readFileSync.

Aunque ambas funciones realizan tareas similares, es decir, leer archivos del disco, la diferencia radica en la forma en que se ejecutan estas funciones, que explicaremos con más detalle en las secciones a continuación.

Usando fs.readFileSync

La función readFileSync lee datos de un archivo de forma síncrona. Esta función bloquea la ejecución del resto del código hasta que se leen todos los datos de un archivo. La función es particularmente útil cuando su aplicación tiene que cargar los ajustes de configuración antes de poder realizar cualquier otra tarea.

Para continuar con nuestro ejemplo, usemos esta función para leer el archivo "student.json" que creamos anteriormente, usando la función readFileSync. Agregue el siguiente código a un archivo '.js':

1
2
3
4
5
6
7
'use strict';

const fs = require('fs');

let rawdata = fs.readFileSync('student.json');
let student = JSON.parse(rawdata);
console.log(student);

En el código de Node.js anterior, primero cargamos el módulo fs en nuestra aplicación. A continuación, usamos la función readFileSync y le pasamos la ruta de archivo relativa al archivo que queremos leer. Si imprime el objeto rawdata en la consola, verá los datos sin procesar (en un Búfer) en la pantalla de la consola:

1
<Buffer 7b 20 0a 20 20 20 20 22 6e 61 6d 65 22 3a 20 22 53 61 72 61 22 2c 0a 20 20 20 20 22 61 67 65 22 3a 20 32 33 2c 0a 20 20 20 20 22 67 65 6e 64 65 72 22 ... >

Sin embargo, queremos leer el archivo en su formato JSON, no los datos hexadecimales sin procesar. Aquí es donde entra en juego la función JSON.parse. Esta función maneja el análisis de los datos sin procesar, los convierte en texto ASCII y analiza los datos JSON reales en un objeto JavaScript. Ahora, si imprime el objeto estudiante en la consola, obtendrá el siguiente resultado:

1
2
3
4
5
{ name: 'Sara',
  age: 23,
  gender: 'Female',
  department: 'History',
  car: 'Honda' }

Como puede ver, el JSON de nuestro archivo se cargó con éxito en el objeto student.

Usando fs.readFile

Otra forma de leer un archivo JSON en Node.js es usando la función readFile. A diferencia de la función readFileSync, la función readFile lee datos de archivos de forma asíncrona. Cuando se llama a una función readFile, el proceso de lectura del archivo comienza e inmediatamente el control cambia a la siguiente línea ejecutando las líneas restantes de código. Una vez que se han cargado los datos del archivo, esta función llamará a la función de devolución de llamada que se le proporcionó. De esta manera, no está bloqueando la ejecución del código mientras espera que el sistema operativo se comunique con usted con los datos.

En nuestro ejemplo, la función readFile toma dos parámetros: la ruta al archivo que se va a leer y la función de devolución de llamada que se llamará cuando el archivo se lea por completo. Opcionalmente, también puede incluir un parámetro con opciones, pero no las cubriremos en este artículo.

Eche un vistazo al siguiente ejemplo para entender cómo usar la función readFile.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
'use strict';

const fs = require('fs');

fs.readFile('student.json', (err, data) => {
    if (err) throw err;
    let student = JSON.parse(data);
    console.log(student);
});

console.log('This is after the read call');

El código anterior hace exactamente lo que hizo nuestro fragmento de código anterior (con una llamada console.log adicional), pero lo hace de forma asíncrona. Estas son algunas de las diferencias, que quizás hayas notado:

  • (err, data) => {}: esta es nuestra función de devolución de llamada que se ejecuta una vez que el archivo se lee por completo
  • err: Dado que no podemos usar fácilmente try/catch con código asíncrono, la función en su lugar nos da un objeto err si algo sale mal. Es nulo si no hubo errores

También puede haber notado que imprimimos una cadena en la consola inmediatamente después de llamar a readFile. Esto es para mostrarle el comportamiento del código asíncrono. Cuando se ejecuta el script anterior, verá que este console.log se ejecuta antes de que se ejecute la función de devolución de llamada readFile. Esto se debe a que readFile no bloquea la ejecución del código mientras lee datos del sistema de archivos.

La salida del código se verá así:

1
2
3
4
5
6
This is after the read call
{ name: 'Sara',
  age: 23,
  gender: 'Female',
  department: 'History',
  car: 'Honda' }

Como puede ver, la última línea de código en nuestro archivo es en realidad la que aparece primero en la salida.

Usando require

Otro enfoque es utilizar el método require global para leer y analizar archivos JSON. Este es el mismo método que usa para cargar módulos de Node, pero también se puede usar para cargar JSON.

Echa un vistazo al siguiente ejemplo.

1
2
3
4
5
'use strict';

let jsonData = require('./student.json');

console.log(jsonData);

Funciona exactamente como el código readFileSync que mostramos arriba, pero es un método disponible globalmente que puede usar en cualquier lugar, lo que tiene sus ventajas.

Sin embargo, hay algunos inconvenientes de la función require:

  • Require es una función síncrona y se llama solo una vez, lo que significa que las llamadas reciben un resultado en caché. Si el archivo está actualizado, no puede volver a leerlo con este método
  • Su archivo debe tener la extensión '.json', por lo que no puede ser tan flexible. Sin la extensión adecuada, require no trata el archivo como un archivo JSON.

Escribir JSON en un archivo

Similar a las funciones readFile y readFileSync, existen dos funciones para escribir datos en archivos: writeFile y writeFileSync. Como sugieren los nombres, el método writeFile escribe datos en un archivo de forma asíncrona, mientras que la función writeFileSync escribe datos en un archivo de forma síncrona.

Echaremos un vistazo más de cerca en las siguientes secciones.

Usar fs.writeFileSync

La función writeFileSync acepta 2-3 parámetros: la ruta del archivo para escribir datos, los datos para escribir y un parámetro opcional.

Tenga en cuenta que si el archivo aún no existe, se creará uno nuevo para usted. Echa un vistazo al siguiente ejemplo:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
'use strict';

const fs = require('fs');

let student = { 
    name: 'Mike',
    age: 23, 
    gender: 'Male',
    department: 'English',
    car: 'Honda' 
};
 
let data = JSON.stringify(student);
fs.writeFileSync('student-2.json', data);

En el ejemplo anterior, estamos almacenando nuestro objeto JSON student en un archivo llamado "student-2.json". Tenga en cuenta que aquí tenemos que usar la función JSON.stringify antes de guardar los datos. Al igual que necesitábamos analizar los datos en formato JSON cuando leíamos el archivo JSON, necesitamos “encadenar” los datos antes de poder almacenarlos en forma de cadena en el archivo.

Ejecute el código anterior y abra el archivo "student-2.json". Debería ver el siguiente contenido en el archivo:

1
{"name":"Mike","age":23,"gender":"Male","department":"English","car":"Honda"}

Aunque estos son los datos que queríamos escribir, los datos tienen la forma de una línea de cadena, lo que nos resulta difícil de leer. Si desea que el JSON serializado sea legible por humanos, cambie la función JSON.Stringify de la siguiente manera:

1
let data = JSON.stringify(student, null, 2);

Aquí le indicamos al método que agregue líneas nuevas y un par de sangrías al JSON serializado. Ahora, si abre el archivo "student-2.json", debería ver el texto en el siguiente formato.

1
2
3
4
5
6
7
{
  "name": "Mike",
  "age": 23,
  "gender": "Male",
  "department": "English",
  "car": "Honda"
}
Usar fs.writeFile

Como mencioné anteriormente, la función writeFile se ejecuta de manera asincrónica, lo que significa que nuestro código no está bloqueado mientras los datos se escriben en el archivo. Y al igual que los métodos asincrónicos de antes, necesitamos pasar una devolución de llamada a esta función.

Escribamos otro archivo, "student-3.json", usando la función writeFile.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
'use strict';

const fs = require('fs');

let student = { 
    name: 'Mike',
    age: 23, 
    gender: 'Male',
    department: 'English',
    car: 'Honda' 
};
 
let data = JSON.stringify(student, null, 2);

fs.writeFile('student-3.json', data, (err) => {
    if (err) throw err;
    console.log('Data written to file');
});

console.log('This is after the write call');

La salida del script anterior será:

1
2
This is after the write call
Data written to file

Y nuevamente, puede ver que la última línea de nuestro código aparece primero en la consola ya que nuestra devolución de llamada aún no ha sido llamada. Esto termina ahorrando bastante tiempo de ejecución si tiene una gran cantidad de datos para escribir en su archivo, o si tiene bastantes archivos para escribir.

Más información {#más información}

¿Quiere aprender más sobre los fundamentos de Node.js? Personalmente, recomendaría tomar un curso en línea como Aprenda Node.js por Wes Bos. No solo aprenderá la sintaxis ES2017 más actualizada, sino que podrá crear una aplicación de restaurante de pila completa. Según mi experiencia, crear aplicaciones del mundo real como esta es la forma más rápida de aprender.

Conclusión

A lo largo de este artículo, mostramos cómo puede leer y escribir datos JSON desde y hacia archivos, lo cual es una tarea muy común e importante que debe saber hacer como programador web.

Hay un par de métodos en el módulo fs tanto para leer como para escribir en archivos JSON. Las funciones readFile y readFileSync leerán los datos JSON del archivo de forma asíncrona y síncrona, respectivamente. También puede usar el método require global para manejar la lectura/análisis de datos JSON de un archivo en una sola línea de código. Sin embargo, require es síncrono y solo puede leer datos JSON de archivos con la extensión '.json'.

Del mismo modo, las funciones writeFile y writeFileSync del módulo fs escriben datos JSON en el archivo de manera asincrónica y sincrónica, respectivamente.