Cómo actualizar un valor en un archivo json y guardarlo a través de node.js

84

¿Cómo actualizo un valor en un archivo json y lo guardo a través de node.js? Tengo el contenido del archivo:

var file_content = fs.readFileSync(filename);
var content = JSON.parse(file_content);
var val1 = content.val1;

Ahora quiero cambiar el valor de val1y guardarlo en el archivo.

Nava Polak Onik
fuente

Respuestas:

127

Hacer esto de forma asincrónica es bastante fácil. Es particularmente útil si le preocupa bloquear el hilo (probablemente).

const fs = require('fs');
const fileName = './file.json';
const file = require(fileName);
    
file.key = "new value";
    
fs.writeFile(fileName, JSON.stringify(file), function writeJSON(err) {
  if (err) return console.log(err);
  console.log(JSON.stringify(file));
  console.log('writing to ' + fileName);
});

La advertencia es que json se escribe en el archivo en una línea y no se embellece. ex:

{
  "key": "value"
}

estarán...

{"key": "value"}

Para evitar esto, simplemente agregue estos dos argumentos adicionales a JSON.stringify

JSON.stringify(file, null, 2)

null- representa la función de reemplazo. (en este caso no queremos alterar el proceso)

2 - representa los espacios a sangrar.

Seth
fuente
50
//change the value in the in-memory object
content.val1 = 42;
//Serialize as JSON and Write it to a file
fs.writeFileSync(filename, JSON.stringify(content));
Peter Lyons
fuente
6
En general, sería mejor usar una escritura asincrónica ya que este es el enfoque principal de Node. Por supuesto, sin ver el código que lo rodea, sería difícil dar una respuesta definitiva. Es poco probable que realmente necesite una sincronización, a menos que necesite estar absolutamente seguro de que nada más puede suceder hasta que se complete la escritura. Además, por supuesto, esto debería tener un verificador de errores, ya que NUNCA puede estar seguro de que la escritura de un archivo se realizará correctamente.
Julian Knight
4
async vs sync depende exactamente de lo que esté haciendo en qué contexto. Si se trata de un servicio de red, necesita async. Para una utilidad de línea de comando, la sincronización es el paradigma apropiado en la mayoría de los casos simples, pero el simple hecho de decir "async es mejor" no es correcto. Mi fragmento se basa en el fragmento OP para el contexto. La pregunta tampoco es sobre el manejo de errores y si la escritura del archivo falla, salir con un seguimiento de pila es un comportamiento predeterminado razonable porque no hay mucho que pueda hacer para recuperarse de eso.
Peter Lyons
Debido a que el nodo se basa en un bucle, la asincrónica casi siempre es mejor, por lo que no bloquea el bucle, esta no es una reacción instintiva en absoluto, simplemente una práctica estándar para el desarrollo de nodos. Ya dije que depende del requisito y no creo que la Q diga nada sobre la línea de comando. Además, en general, si esto es parte de un conjunto de código más grande (no aclarado por el OP), entonces el manejo de errores es siempre inteligente y una mejor práctica. Vaciar un seguimiento de pila está bien para los desarrolladores, pero es una mierda para todos los demás.
Julian Knight
22
async es una técnica de concurrencia. Si necesita concurrencia, se requiere async para que el nodo funcione correctamente (no "mejor"). Si no tiene concurrencia, no necesita async. El punto es que debe comprender realmente qué hace async por usted y por qué. No es inherentemente "mejor" sin ninguna razón y no es necesario que lo memorice como una "mejor práctica". Si el OP está escribiendo una utilidad de línea de comando para alterar un archivo JSON y luego salir, async complica el código sin ninguna razón ya que no se requiere la concurrencia.
Peter Lyons
Estoy construyendo una herramienta de línea de comandos de nodo. Si no está sincronizado, el archivo podría bloquearse cuando la salida de mi herramienta se encadena a la siguiente herramienta. Hay muy buenas razones para usar la sincronización. Y buenas razones para usar async.
TamusJRoyce
3

Además de la respuesta anterior, agregue el directorio de ruta de archivo para la operación de escritura

 fs.writeFile(path.join(__dirname,jsonPath), JSON.stringify(newFileData), function (err) {}
satej sarker
fuente
2
// read file and make object
let content = JSON.parse(fs.readFileSync('file.json', 'utf8'));
// edit or add property
content.expiry_date = 999999999999;
//write file
fs.writeFileSync('file.json', JSON.stringify(content));
Apoorva Shah
fuente
0

Para aquellos que buscan agregar un elemento a una colección json

function save(item, path = './collection.json'){
    if (!fs.existsSync(path)) {
        fs.writeFile(path, JSON.stringify([item]));
    } else {
        var data = fs.readFileSync(path, 'utf8');  
        var list = (data.length) ? JSON.parse(data): [];
        if (list instanceof Array) list.push(item)
        else list = [item]  
        fs.writeFileSync(path, JSON.stringify(list));
    }
}
Azotado
fuente
0

Recomendaría encarecidamente no utilizar funciones síncronas (de bloqueo), ya que tienen otras operaciones simultáneas . En su lugar, use fs.promises asincrónicos :

const fs = require('fs').promises

const setValue = (fn, value) => 
  fs.readFile(fn)
    .then(body => JSON.parse(body))
    .then(json => {
      // manipulate your data here
      json.value = value
      return json
    })
    .then(json => JSON.stringify(json))
    .then(body => fs.writeFile(fn, body))
    .catch(error => console.warn(error))

Recuerde que setValuedevuelve una promesa pendiente, deberá usar la función .then o, dentro de las funciones asíncronas, el operador await .

// await operator
await setValue('temp.json', 1)           // save "value": 1
await setValue('temp.json', 2)           // then "value": 2
await setValue('temp.json', 3)           // then "value": 3

// then-sequence
setValue('temp.json', 1)                 // save "value": 1
  .then(() => setValue('temp.json', 2))  // then save "value": 2
  .then(() => setValue('temp.json', 3))  // then save "value": 3
ΔO 'deltazero'
fuente
0

Guardar datos después de completar la tarea

fs.readFile("./sample.json", 'utf8', function readFileCallback(err, data) {
        if (err) {
          console.log(err);
        } else {
          fs.writeFile("./sample.json", JSON.stringify(result), 'utf8', err => {
            if (err) throw err;
            console.log('File has been saved!');
          });
        }
      });
Gaurav Mogha
fuente