Bestandssysteem in javascript

Crowl.filesystem.js

Crowl.filesystem.js simuleert een bestandssysteem in een webbrowser met behulp van IndexedDB. Dit is een krachtige interface in webbrowsers waarmee data structureel en permanent opgeslagen kan worden. De javascript-class vergemakkelijkt het beheer van bestanden zoals het aanmaken, lezen, verwijderen en opslaan van zowel tekstuele als binaire bestanden. Deze benadering maakt het mogelijk om een complexe file management applicatie direct binnen een browseromgeving te draaien.

Terwijl cookies zijn gelimiteerd in opslagcapaciteit (4kb) is CrowlFileSystem niet gelimiteerd. Het kan gigabytes aan data bewaren binnen een webpagina in de browser. Via CrowlServer kan het die bestanden ook eenvoudig uitwisselen met een online databank.

Waarom IndexedDB voor de simulatie van bestandssysteem?

IndexedDB is een uitstekende keuze voor het simuleren van een bestandssysteem in een browser om meerdere redenen:

  1. Opslagcapaciteit: Het biedt aanzienlijke opslagruimte vergeleken met andere client-side opslagopties zoals LocalStorage, wat essentieel is voor bestandsbeheer.
  2. Asynchrone Interface: Het biedt een asynchrone API, die voorkomt dat UI-blocking optreedt bij het lezen of schrijven van grote bestanden.
  3. Structuur: Het ondersteunt het opslaan van gegevens in object stores en het indexeren van deze gegevens, wat helpt bij het efficiënt opvragen en organiseren van bestandsgegevens.
  4. Flexibiliteit: Het ondersteunt het werken met verschillende datatypes, inclusief blobs en typed arrays, wat ideaal is voor het hanteren van zowel tekstuele als binaire bestanden.

Mogelijkheden en functies van de class

  1. Bestanden aanmaken: Het script biedt functies om zowel tekstuele als binaire bestanden aan te maken.
  2. Bestanden lezen: Functies om zowel tekstuele als binaire bestanden te lezen en de inhoud weer te geven.
  3. Bestanden verwijderen: Mogelijkheid om bestanden te verwijderen uit de database.
  4. Bestanden opsommen: Een functie om alle opgeslagen bestanden op te halen en te sorteren op verschillende criteria zoals naam, datum, grootte, en MIME-type.
  5. Mappen aanmaken: Je kan mappen aanmaken en daar bestanden aan toevoegen, net zoals in Windows verkenner of Mac OS Finder.
  6. Hernoemen: je kan bestanden en mappen hernoemen.
  7. Verwijderen: je kan bestanden en mappen verwijderen.
  8. Kopiëren en plakken: je kan bestanden kopiëren en plakken in een andere map.
  9. Ruimtebeheer: Het script bevat functionaliteit om de beschikbare en gebruikte opslagruimte te schatten.
  10. Bestandsdownload: Het faciliteert het downloaden van bestanden door het creëren van een URL naar de blob-data.
  11. Bestandsencodering en -decodering: Voor binaire bestanden biedt het script mogelijkheden om deze te encoderen naar een Uint8Array en te decoderen vanuit deze array.
  12. Exporteren: je kan alle bestanden en mappen exporteren als CSV en SQL
  13. ZIP en download: Je kan individuele bestanden downloaden en mappen met inhoud downloaden als ZIP.
  14. ...

Voorbeeldgebruik

  1. Constructor: Initialiseert een IndexedDB database genaamd "Crowl SimOS 13" en maakt twee object stores aan: "folders" en "files".
  2. exportToCsv: Exporteert alle records van een gegeven object store naar een CSV-bestand.
  3. exportToSql: Exporteert alle records van een gegeven object store naar SQL-insert statements.
  4. loadFileSaver: Laadt de FileSaver.js-bibliotheek dynamisch in de pagina.
  5. loadJsZip: Laadt de JSZip-bibliotheek dynamisch in de pagina (na het laden van FileSaver.js).
  6. getFolderIdByName: Haalt de ID op van een folder op basis van de naam.
  7. listFilesInFolder: Lijst alle bestanden in een opgegeven folder, gesorteerd op een attribuut.
  8. createBinaryFile: Maakt een binair bestand aan in een opgegeven folder.
  9. encodeBinaryFile: Converteert een bestand naar een Uint8Array.
  10. decodeTextFile: Decodeert tekstgegevens naar een downloadbaar bestand.
  11. decodeBinaryFile: Decodeert binaire gegevens naar een downloadbaar bestand.
  12. readBinaryFile: Leest een binair bestand uit de database.
  13. readAndDecodeBinaryFile: Leest en decodeert een binair bestand uit de database.
  14. listAllFiles: Lijst alle bestanden in de database, gesorteerd op een attribuut.
  15. listAllFolders: Lijst alle folders in de database, gesorteerd op een attribuut en optioneel gefilterd op een ouder folder ID.
  16. getAllFilesWithMime: Haalt alle bestanden met hun MIME-types op.
  17. formatFileSystem: Verwijdert en herinitialiseert de database.
  18. createFolder: Maakt een nieuwe folder aan.
  19. createFile: Maakt een nieuw bestand aan in een opgegeven folder.
  20. moveFolder: Verplaatst een folder naar een nieuwe ouder folder.
  21. moveFile: Verplaatst een bestand naar een nieuwe folder.
  22. renameFolder: Hernoemt een folder.
  23. renameFile: Hernoemt een bestand.
  24. copyAndPasteFile: Kopieert een bestand naar een nieuwe folder.
  25. deleteFolder: Verwijdert een folder.
  26. deleteFile: Verwijdert een bestand.
  27. listSubfolders: Lijst alle subfolders van een gegeven ouder folder.
  28. openFolder: Haalt alle bestanden en subfolders van een gegeven folder op.
  29. downloadFile: Downloadt een bestand door het te decoderen.
  30. downloadFolderAsZip: Downloadt alle bestanden in een folder als een zip-bestand.
  31. openFile: Opent een bestand en toont de inhoud.
  32. openSpecificFile: Opent een specifiek bestand en toont de inhoud.
  33. executeSQL: Voert een SQL-opdracht uit op de database.
  34. handleInsert: Verwerkt een SQL-insert statement.
  35. handleUpdate: Verwerkt een SQL-update statement.
  36. handleSelect: Verwerkt een SQL-select statement.
  37. handleDelete: Verwerkt een SQL-delete statement.
  38. searchFiles: Zoekt naar bestanden op basis van een zoekterm.
  39. exportDatabase: exporteert de volledige structuur en inhoud van de databank naar een JSON-bestand
  40. importDatabase: importeert een eerder geëxporteerd JSON-bestand.

Initialisatie

const fs = new CrowlFileSystem();

Voorbeeldcode functies

 /*
        copyAndPasteFile(fileId, newFolderId)
        bestand kopiëren en plakken in een andere map
        */
        cpf.addEventListener("click", async function(data) {
            try {
                var d = await fs.copyAndPasteFile(18, 1);
                console.log(d);
            } catch (error) {
                console.error("Er is een fout opgetreden:", error);
            }
        });

        /*
        Een bestand verhuizen naar een andere map
        moveFile(fileId, newFolderId)
        */
        mofi.addEventListener("click", async function(data) {
            try {
                var d = await fs.moveFile(18, 2);
                console.log(d);
            } catch (error) {
                console.error("Er is een fout opgetreden:", error);
            }
        });

        /*
        Een bestand zoeken op basis van een zoekterm.
        Zoekt op naam en inhoud.
        */
        buttonq.addEventListener("click", async function(data) {
            try {
                var q = document.getElementById("fquery").value;
                var d = await fs.searchFiles(q);
                console.log(d);
            } catch (error) {
                console.error("Er is een fout opgetreden:", error);
            }
        });

        /*
        Een map verhuizen naar een andere map (als submap)
        moveFolder(idmap,idbestemmingsmap)
        */
        moveme.addEventListener("click", async function(data) {
            try {
                var d = await fs.moveFolder(2, 1);
                console.log(d);
            } catch (error) {
                console.error("Er is een fout opgetreden:", error);
            }
        });

        /*
        Bestand downloaden op id
        */
        down.addEventListener("click", async function(data) {
            try {
                await fs.downloadFile(17);
            } catch (error) {
                console.error("Er is een fout opgetreden:", error);
            }
        });

        /*
        Een map verwijderen op id
        */
        dfo.addEventListener("click", async function(data) {
            try {
                var d = await fs.deleteFolder(3);
                console.log(d);
            } catch (error) {
                console.error("Er is een fout opgetreden:", error);
            }
        });


        /*
        Een map hernoemen
        renameFolder(folderID, nieuweNaam);
        */
        rf.addEventListener("click", async function(data) {
            try {
                var d = await fs.renameFolder(2, "Een map met prentjes");
                console.log(d);
            } catch (error) {
                console.error("Er is een fout opgetreden:", error);
            }
        });

        /*
        Een lijst van alle bestanden in de databank
        listAllFiles(order);
        Je kan ordenen op name,id of aanmaakdatum
        */
        explorer.addEventListener("click", async function(data) {
            try {
                var d = await fs.listAllFiles("name");
                console.log(d);
            } catch (error) {
                console.error("Er is een fout opgetreden:", error);
            }
        });

        /*
        Lijst van alle bestanden in een map
        listFilesInFolder(folderId);
        */
        filesinfolder.addEventListener("click", async function(data) {
            try {
                var d = await fs.listFilesInFolder(2);
                console.log(d);
            } catch (error) {
                console.error("Er is een fout opgetreden:", error);
            }
        });

        /*
        Lijst van alle mappen
        */
        allfolders.addEventListener("click", async function(data) {
            try {
                var d = await fs.listAllFolders();
                console.log(d);
            } catch (error) {
                console.error("Er is een fout opgetreden:", error);
            }
        });

        /*
        Een map maken met een specifieke naam.
        */
        document.getElementById('createFolder').addEventListener('click', async() => {
            try {
                const folderId = await fs.createFolder('Nieuwe Map');
                console.log(`Map gecreëerd met ID: ${folderId}`);
            } catch (error) {
                console.error('Fout bij het maken van de map:', error);
            }
        });

        /*
        Een (tekst)bestand maken
        createFile(bestandsnaam,inhoud,folderId);
        */
        document.getElementById('createFile').addEventListener('click', async() => {
            try {
                // Voeg een tekstbestand toe aan de eerder gecreëerde map (folderId moet bekend zijn)
                const fileId = await fs.createFile('Voorbeeld' + fi + '.txt', 'Dit is de inhoud van het bestand', 2);
                console.log(`Bestand gecreëerd met ID: ${fileId}`);
                fi++;
            } catch (error) {
                console.error('Fout bij het maken van het bestand:', error);
            }
        });

        /*
        Een map zippen en downloaden
        loadJsZip(). Zip-bibliotheek laden (eenmalig)
        downloadFolderAsZip(folderId);
        */
        document.getElementById('downloadZip').addEventListener('click', async() => {
            try {
                await fs.loadJsZip();
                await fs.downloadFolderAsZip(2);
                console.log('Zip-bestand succesvol gedownload.');
            } catch (error) {
                console.error('Fout bij het downloaden van de zip:', error);
            }
        });

        /*
        Databank/bestandssysteem formatteren en wissen
        */
        format.addEventListener("click", function() {
            console.log("db verwijderen?");
            fs.formatFileSystem();
        })

        /*
        files of folders exporteren naar CSV of SQL
        exportToSql("files")
        exportToCsv("files")
        */
        sql.addEventListener("click", function() {
            fs.exportToSql("files").then(sql => {
                console.log("SQL Statements: ", sql);
            }).catch(error => {
                console.error("Er is een fout opgetreden:", error);
            });


            fs.exportToCsv("files").then(csv => {
                console.log("CSV Data: ", csv);
            }).catch(error => {
                console.error("Er is een fout opgetreden bij het exporteren naar CSV:", error);
            });

        });

SQL-statements

fs.executeSQL(SQL-query).then(result => console.log(result)).catch(error => console.error(error));

De databank exporteren als backup

Bij fs.exportDatase(false) krijg je een uitvoer van de json-databank. Plaats je de parameter op "true" dan wordt de json automatisch gedownload. 

document.getElementById('exportButton').addEventListener('click', async() => { 
   try {
      const data = await fs.exportDatabase;
      console.log(data);
   } catch (error) {
      console.error("Fout bij het ophalen van de database data:", error);
   }
});
Volgende pagina