Aprende a trabajar con el ciclo de vida de un archivo en Electron.


Para trabajar con el ciclo de vida de un archivo (CRUD), usaremos los componentes de dialogos (dialog) y el sistema de archivos (filesystem).

El módulo de dialogos provee una API para mostrar dialogos nativos del sistema, como por ejemplo el dialogo de abrir archivos o alertas, de esta manera la "aplicación web" dentro de Electron puede generar la misma experiencia que usar aplicaciones nativas.

Cargando dependencias requeridas

Necesitamos declarar las siguiente variables para poder ejecutar todas las tareas que queremos ejecutar como por ejemplo guarda, abrir, borrar etc, incluyendo los dialogos nativos del sistema operativo.

var remote = require('remote'); // Cargar el componente remote que contiene la dependencia de los dialogos
var dialog = remote.require('dialog'); // Cargar los dialogos
var fs = require('fs'); // Cargar el sistema de archivos para ejecutar nuestras tareas de archivos

Nota: en las ultimas versiones de electron (>= 1), usa el siguiente snippet para acceder a los dialogos.

var app = require('electron').remote; 
var dialog = app.dialog;

Crear un archivo

Para crear un archivo vamos a usar el sistema de archivos (file system) y en este caso, el dialogo nativo para guardar el archivo (para poder conseguir el directorio):

// Puedes obviamente dar una direccion completa sin usar el dialogo (C:/Program Files/path/myfileexample.txt)
dialog.showSaveDialog(function (fileName) {
       if (fileName === undefined){
            console.log("No guardaste el archivo");
            return;
       }
       // filename es una cadena de texto que contiene la direccion y el nombre del archivo "creado" con el dialogo
       fs.writeFile(fileName, content, function (err) {
           if(err){
               alert("Ha ocurrido un error creando el archivo: "+ err.message)
           }
                        
           alert("El archivo ha sido creado satisfactoriamente");
       });
}); 

Create file dialog

Leer contenido de un archivo

Para buscar un archivo, usaremos el dialogo nativo del sistema y el archivo será leido con el método readFile del sistema de archivos:

dialog.showOpenDialog(function (fileNames) {
        // fileName es un array que contiene todos los archivo(s) seleccionado(s)
       if(fileNames === undefined){
            console.log("No se selecciono ningun archivo");
       }else{
            readFile(fileNames[0]);
       }
});

function readFile(filepath){
    fs.readFile(filepath, 'utf-8', function (err, data) {
          if(err){
              alert("Ha ocurrido un error abriendo el archivo:" + err.message);
              return;
          }
          // Cambia cómo manipular el contenido del archivo
          console.log("El contenido del archivo es : " + data);
    });
}

// Cabe destacar que en el ejemplo anterior, se manejara un solo archivo si quieres que se pueda escoger multiples archivos, cambia las propiedades
// y obviamente itera con un ciclo for el array para leer cada uno de los archivos
dialog.showOpenDialog({ properties: [ 'openFile', 'multiSelections',function(fileNames){
  console.log(fileNames);
}]});

Open file dialog electron

Sobreescribir contenido de archivo

Para actualizar un archivo existente, necesitamos solamente el directorio (puedes usar el dialogo de seleccionar archivo para seleccionar un archivo existente) usando el siguiente código:

var filepath = "C:/directorio-cualquiera/archivo-existente.txt";// you need to save the filepath when you open the file to update without use the filechooser dialog againg
var content = "Este es el nuevo contenido del archivo";

fs.writeFile(filepath, content, function (err) {
      if(err){
            alert("Ha ocurrido un error actualizando el archivo"+ err.message);
            console.log(err);
            return;
      }
                    
      alert("El archivo ha sido guardado satisfactoriamente");
 }); 

Borrar un archivo

Para borrar un archivo solamente necesitas el directorio del archivo, verificar que el archivo exista y eliminarlo usando el método unlink.

var filepath = "C:/directorio-cualquiera/archivo-existente.txt";
fs.exists(filepath, function(exists) {
      if(exists) {
            // El archivo existe, borrar
            fs.unlink(filepath,function(err){
                  if(err){
                      alert("Ha ocurrido un error al eliminar el archivo"+ err.message);
                      console.log(err);
                      return;
                  }
              console.log("Archivo satisfactoriamente eliminado");
            );
      } else {
           alert("El archivo no existe, por lo tanto no se puede borrar");
      }
});

Bastante sencillo, verdad?

Seleccionar una carpeta

Puedes seleccionar una carpeta usando el selector de carpetas nativos:

dialog.showOpenDialog({
    title:"Selecciona una carpeta",
    properties: ["openDirectory"]
},function (folderPaths) {
    // folderPaths es un array que contiene todos los directorios seleccionados
    if(fileNames === undefined){
        console.log("No se escogio una carpeta");
        return;
    }else{
        console.log(folderPaths);
    }
});

Ejemplo funcional

El siguiente archivo HTML puede ser usado para probar y entender como el sistema de archivos funciona. El código generará una simple interfaz y acciones sencillas usando Javascript.

Crud Electron example

<!DOCTYPE html>
<html>
    <head>
        <title>Our Code World</title>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
    </head>
    <body>
        <div>
            <div style="text-align:center;">
                <input type="text" placeholder="Por favor selecciona un archivo" id="actual-file" disabled="disabled"/>
                <input type="button" value="Escoge un archivo" id="select-file"/>
            </div>
            <br><br>
            <textarea id="content-editor" rows="5"></textarea><br><br>
            <input type="button" id="save-changes" value="Save changes"/>
            <input type="button" id="delete-file" value="Delete file"/>
        </div>
        <hr>
        <div style="text-align:center;">
            <p>
                El contenido del archivo será el mismo del editor.
            </p>
            <input type="button" value="Escoge un archivo" id="create-new-file"/>
        </div>
        <script>
            var app = require('electron').remote; 
            var dialog = app.dialog;
            var fs = require('fs');
                
            document.getElementById('select-file').addEventListener('click',function(){
                dialog.showOpenDialog(function (fileNames) {
                    if(fileNames === undefined){
                        console.log("No file selected");
                    }else{
                        document.getElementById("actual-file").value = fileNames[0];
                        readFile(fileNames[0]);
                    }
                }); 
            },false);
            
            document.getElementById('save-changes').addEventListener('click',function(){
                var actualFilePath = document.getElementById("actual-file").value;
                
                if(actualFilePath){
                    saveChanges(actualFilePath,document.getElementById('content-editor').value);
                }else{
                    alert("Por favor selecciona un archivo primero");
                }
            },false);
            
            document.getElementById('delete-file').addEventListener('click',function(){
                var actualFilePath = document.getElementById("actual-file").value;
                
                if(actualFilePath){
                    deleteFile(actualFilePath);
                    document.getElementById("actual-file").value = "";
                    document.getElementById("content-editor").value = "";
                }else{
                    alert("Por favor selecciona un archivo primero");
                }
            },false);
            
            document.getElementById('create-new-file').addEventListener('click',function(){
                var content = document.getElementById("content-editor").value;
                
                dialog.showSaveDialog(function (fileName) {
                    if (fileName === undefined){
                        console.log("No guardaste el archivo.");
                        return;
                    }
                    
                    fs.writeFile(fileName, content, function (err) {
                        if(err){
                            alert("Ha ocurrido un error al crear el archivo"+ err.message)
                        }
                        
                        alert("El archivo ha sido guardado satisfactoriamente");
                    });
                }); 
            },false);
            
            function readFile(filepath) {
                fs.readFile(filepath, 'utf-8', function (err, data) {
                    if(err){
                        alert("Ha ocurrido un error al leer el archivo :" + err.message);
                        return;
                    }
                    
                    document.getElementById("content-editor").value = data;
                });
            }
            
            function deleteFile(filepath){
                fs.exists(filepath, function(exists) {
                    if(exists) {
                        // File exists deletings
                        fs.unlink(filepath,function(err){
                            if(err){
                                alert("Ha ocurrido un error al actualizar el archivo"+ err.message);
                                console.log(err);
                                return;
                            }
                        });
                    } else {
                        alert("Este archivo no existe, no se puede borrar");
                    }
                });
            }
            
            function saveChanges(filepath,content){
                fs.writeFile(filepath, content, function (err) {
                    if(err){
                        alert("Ha ocurrido un error actualizando el archivo"+ err.message);
                        console.log(err);
                        return;
                    }
                    
                    alert("El archivo ha sido guardado satisfactoriamente");
                }); 
            }
        </script>
    </body>
</html>

Que te diviertas !


Ingeniero de Software Senior en EPAM Anywhere. Interesado en la programación desde los 14 años, Carlos es un programador autodidacta, fundador y autor de la mayoría de los artículos de Our Code World.

Conviertete en un programador más sociable

Patrocinadores