Electron function to read a local file - FS - Not reading
Asked Answered
W

3

21

I have an electron project when I need to get electron to read a local file.

Right now what I have is this, where it loads and displays the contents of a html file.

I just need it to read a file and store it on a variable for now.

Here is my current main.js:

 const {app, BrowserWindow } = require('electron');
const path = require('path');
const url = require('url');
var fs = require('fs');

let mainWindow;

function createNewWindow() {
  mainWindow = new BrowserWindow({
    width: 1300,
    height: 1000,
    minWidth: 600,
    minHeight: 400,
    title: 'Test App'
  })
}

function loadInitialUrl() {
  mainWindow.loadURL(url.format({
    pathname: path.join(__dirname, 'index.html'),
    protocol: 'file:',
    slashes: true
  }))
}

function closeApplication() {
  mainWindow.on('closed', () => {
    mainWindow = null;
})
}


app.on('ready', function(){
  createNewWindow();
  loadInitialUrl();
  mainWindow.setMenu(null);
  mainWindow.openDevTools();
  fs.readFile('./README.md', 'utf8', function (err,data) {
    if (err) {
      return console.log(err);
    }
    console.log(data);
  });
  mainWindow.on('closed', function() {mainWindow = null;});
});

How can I do this as it's not showing the contents of the README.md file in the console.log

Whitish answered 1/5, 2017 at 16:17 Comment(2)
possible duplicate of Open external file with ElectronHorwitz
make sure the path is correct. what is the current output of log?Masurium
M
27

Basically you need to do the following things.

1.Loading required dependencies

var remote = require('remote'); // Load remote compnent that contains the dialog dependency
var dialog = remote.require('dialog'); // Load the dialogs component of the OS
var fs = require('fs'); // Load the File System to execute our common tasks (CRUD)

2.Read file content

dialog.showOpenDialog((fileNames) => {
    // fileNames is an array that contains all the selected
    if(fileNames === undefined){
        console.log("No file selected");
        return;
    }

    fs.readFile(filepath, 'utf-8', (err, data) => {
        if(err){
            alert("An error ocurred reading the file :" + err.message);
            return;
        }

        // Change how to handle the file content
        console.log("The file content is : " + data);
    });
});

3.Update existing file content

 var filepath = "C:/Previous-filepath/existinfile.txt";// you need to save the filepath when you open the file to update without use the filechooser dialog againg
var content = "This is the new content of the file";

fs.writeFile(filepath, content, (err) => {
    if (err) {
        alert("An error ocurred updating the file" + err.message);
        console.log(err);
        return;
    }

    alert("The file has been succesfully saved");
});

For more read please visit here :) Thanks..

One more thing to add..Please check that your path to file is correct. You could do something similar to below.

var path = require('path');
var p = path.join(__dirname, '.', 'README.md');
Masurium answered 1/5, 2017 at 16:27 Comment(6)
I'm not looking for a file dialog...just to read the contents of a local file and maybe show in the console.logWhitish
@JakeBrown777 if you just want to read file..and you know the file path then fs.readFile(filepath,.. will doMasurium
In 2. Read the file with dialog, how can I obtain the file path to do fs.weriteFile(filepath,..)?Impulsive
Hi @Anand, I think fileNames parameter passed to showOpenDialog's callback contains the filepath. You can access it like var filepath = fileNames[0]Masurium
Also see this reference=> tutorialspoint.com/electron/electron_system_dialogs.htmMasurium
As of Electron 20, it is no longer possible to do it this way, as there is only a very limited subset of the filesystem available to the preload js file, and none to the main entry point to the file. Would need to use a combination of contextBridge.exposeInMainWorld in the preload.js and icpMain.handle from the main.js file. See: electronjs.org/docs/latest/tutorial/tutorial-preloadBrigettebrigg
S
7

Just one update information for the accepted answer. After the update of electron, you can directly use

const { dialog } = require('electron');

to import dialog.

And for remote, if you need to use it, you also need:

const { remote } = require('electron');

https://www.electronjs.org/docs/latest/api/dialog/

Scrim answered 23/7, 2019 at 0:4 Comment(0)
B
0

The previous answers are no longer correct as of Electron 20.

This would need to use inter-process connector (IPC) code to relay from the main process that has access to fs and require.

It's like a pub-sub system where the main process has a listener for a key, e.g.:

// main.js
const { app, BrowserWindow, ipcMain } = require('electron')
const path = require('node:path')
const fs = require('fs')


const createWindow = () => {
  const win = new BrowserWindow({
    width: 1400,
    height: 1000,
    webPreferences: {
      preload: path.join(__dirname, 'preload.js')
    }
  })
  
  win.loadFile('index.html')
}

app.whenReady().then(() => {
  // The event listener
  ipcMain.handle('readFile', async (event) => {
    return fs.readFileSync(path.join(__dirname, 'README.md'), 'utf-8')
  })

And your preload.js contains the trigger to load file:

// preload.js
const { ipcRenderer } = require('electron')

// Note: This is a good place to put your Electron-only client-side JS code.

const loadFile = async filepath => {
  // Invoking the event
  const contents = await ipcRenderer.invoke('readFile', filepath)
  // Do whatever you want with the contents here
})

loadFile()

Note: If you need the DOM to load first, it may make sense to run loadFile in:

window.addEventListener('DOMContentLoaded', () => {
  loadFile()
})
Brigettebrigg answered 17/2 at 3:21 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.