【问题标题】:How to read a local file in Javascript (Running from an Electron App)如何在 Javascript 中读取本地文件(从 Electron 应用程序运行)
【发布时间】:2021-02-18 18:43:27
【问题描述】:

我已经搜索了一个多小时左右,但我找不到我的问题的答案。有没有办法从本地文件中获取文本,只使用一个普通的旧文件 URL?

我找到了许多通过文件输入 HTML 标记读取文件的方法,但我遇到了令人难以置信的痛苦,在我的 PC 上找到一个可以使用普通旧 JS 查找文件的代码示例。

代码将在电子应用程序中。

我需要代码示例。像这样的:

readFile("file:\\\\C:\path\to\file.txt","text/plain");

readFile(url,mimetype){
 ....
}

【问题讨论】:

    标签: javascript file methods io electron


    【解决方案1】:

    如果您想在 Electron 中读取文件,您必须了解 Electron 应用程序的各个部分。在short中,有一个ma​​in进程和一个renderer进程。主进程拥有并被授予使用节点模块的所有控制权,例如可以读取文件的fs 模块。渲染器进程不应该访问fs模块,而是每当它需要使用fs模块时,它应该请求主进程使用fs,然后返回结果。

    仅供参考,渲染器进程是网页,是 Electron 应用程序的可见部分。

    这种通信称为 IPC(进程间通信)。流程是:

    1. 渲染器进程通过 IPC 向主进程发送消息
    2. 主进程听到消息,然后读取带有fs的文件
    3. 内容/结果通过 IPC 发送回渲染器进程
    4. 渲染器进程现在可以使用文件中的数据做任何事情

    下面是一个非常粗略的例子。

    index.html

    <!doctype html>
    <html lang="en-US">
    <head>
        <meta charset="utf-8"/>
        <title>Title</title>
    </head>
    <body>
        <script>
            // Called when message received from main process
            window.api.receive("fromMain", (data) => {
                console.log(`Received ${data} from main process`);
            });
    
            // Send a message to the main process
            window.api.send("toMain", "some data");
        </script>
    </body>
    </html>
    

    ma​​in.js

    const {
      app,
      BrowserWindow,
      ipcMain
    } = require("electron");
    const path = require("path");
    const fs = require("fs");
    
    // Keep a global reference of the window object, if you don't, the window will
    // be closed automatically when the JavaScript object is garbage collected.
    let win;
    
    async function createWindow() {
    
      // Create the browser window.
      win = new BrowserWindow({
        width: 800,
        height: 600,
        webPreferences: {
          nodeIntegration: false, // is default value after Electron v5
          contextIsolation: true, // protect against prototype pollution
          enableRemoteModule: false, // turn off remote
          preload: path.join(__dirname, "preload.js") // use a preload script
        }
      });
    
      // Load app
      win.loadFile(path.join(__dirname, "dist/index.html"));
    
      // rest of code..
    }
    
    app.on("ready", createWindow);
    
    ipcMain.on("toMain", (event, args) => {
      fs.readFile("path/to/file", (error, data) => {
        // Do something with file contents
    
        // Send result back to renderer process
        win.webContents.send("fromMain", responseObj);
      });
    });
    

    preload.js

    const {
        contextBridge,
        ipcRenderer
    } = require("electron");
    
    // Expose protected methods that allow the renderer process to use
    // the ipcRenderer without exposing the entire object
    contextBridge.exposeInMainWorld(
        "api", {
            send: (channel, data) => {
                // whitelist channels
                let validChannels = ["toMain"];
                if (validChannels.includes(channel)) {
                    ipcRenderer.send(channel, data);
                }
            },
            receive: (channel, func) => {
                let validChannels = ["fromMain"];
                if (validChannels.includes(channel)) {
                    // Deliberately strip event as it includes `sender` 
                    ipcRenderer.on(channel, (event, ...args) => func(...args));
                }
            }
        }
    );
    

    免责声明:我是一个受欢迎的secure electron template 的作者,并写了一篇关于如何使用fs 在Electron 应用程序中读取文件的specific guide。我希望你能读一读,因为它有更多的信息。

    【讨论】:

    • exposeInMainWorld 的领域在做什么?这是一种缺失的解释
    • exposeInMainWorld 只是允许我们定义的函数(这些函数将存在于window,即window.api.send)存在于渲染器/视图进程中。
    【解决方案2】:
    1. 读取文件是使用节点完成的,不依赖于电子
    2. 如果您有创建窗口的代码,请添加此代码
    const fs = require("fs");
    
    function readFile(fileURL,mimeType){
       //readfile does not accept the file:\\\ thing, so we remove it
       const pathToFile = fileURL.replace("file:\\\\",'');
    
       fs.readFile(pathToFile,mimeType,(err,contents)=>{
         if(err){
            console.log(err);
            return;
         }
         console.log(contents);
       })
    }
    
    readFile('C:\\Users\\<userAccount>\\Documents\\test.txt','utf8')
    //If your on windows you'll need to use double backslashes for the paths
    //here's an example regex to do that
    
    pathToFile = pathToFile.replace(/\\/,'\\\\')
    
    

    【讨论】:

      【解决方案3】:

      如果我没记错的话,使用这样的东西应该可以与 fs 模块一起使用。

      fs.readFileSync("/path/to/file.txt");
      

      【讨论】:

      • 当我在网络浏览器中尝试时,这似乎有效...我对 FS 不熟悉,导入 FS 需要做些什么吗?
      • 是的,它是一个节点包“文件系统”,这是关于它的文档npmjs.com/package/file-system
      猜你喜欢
      • 2020-02-22
      • 1970-01-01
      • 2017-05-03
      • 1970-01-01
      • 2014-06-13
      • 2017-11-17
      • 2012-02-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多