当我们的应用程序启动并完全加载窗口时,用户将立即看到一个文件对话框,这将允许他们选择一个文件(参见图4.2)。我们最终从启动过程中删除这个函数调用,并将其分配给UI中的"Open File"按钮。
图4.2 Electron能够在其支持的每个操作系统中触发本机文件对话框。
在图4.3中,我们可以在终端中显示的"Open File"对话框中看到选择的结果。注意dialog.showOpenDialog()返回一个数组。如果在对话框的属性数组中激活多重选择,用户可以选择
多个文件。为了一致性,Electron总是返回一个数组。
图4.3 选择文件后,文件的完整路径将被记录到终端窗口中的控制台。
使用Node读取文件dialog.showOpenDialog()返回一个数组,其中包含用户选择的文件的路径,但它并不代表我们阅读这些文件。根据构建的文件类型,我们可能希望以不同的方式处理打开文件。在这个应用程序中,文件的内容被读取并立即显示在UI中。当用户选择文件时,处理复制图像或将图像上载到外部服务的不同应用程序可能采用相反的方法。另外一个应用程序可能会在播放列表中添加一个大的电影供以后观看。在这种情况下,立即打开大文件是浪费时间。
Node提供了一组用于处理其标准库中的文件的工具。内置的fs库处理常见的文件系统操作,比如读取和写入文件,所以应该要求它位于app/main.js的顶部。
列表 导入Node的fs模块: ./app/main.js
const { app, BrowserWindow, dialog } = require('electron'); const fs = require('fs'); //引入Node fs库 app.on( 'ready', ()=> {...}); // 为清楚起见省略了代码。 const getFileFromUser = () => { const files = dialog.showOpenDialog(mainWindow, { properties: ['openFile'] }); if (!files) {return;} const file = files[0]; //从数组中取出第一个文件 const content = fs.readFileSync(file).toString(); //从文件中读取,并将生成的缓冲区转换为字符串。 console.log(content); }在清单4.4中,应用程序一次只打开一个文件。files[0]从dialog.showOpenDialog()中选择数组中的第一个和唯一文件路径。在fs.readFileSync(file)中,文件路径作为参数传递给fs.readFileSync()。Node不知道打开了什么类型的文件,所以fs.readFileSync()返回一个缓冲区对象。但是,我们知道,在这个特定的应用程序中,我们通常使用纯文本。我们将它转换为一个字符串,并将文件的内容记录到终端,如图4.4所示。
图4.4 文件的内容被记录到用户的终端。
确定打开文件对话框的范围如图4.4所示,getFileFromUser()成功地将文本文件的内容记录到终端。但有一个问题,默认情况下,dialog.showOpenDialog()允许我们打开计算机上的任何文件,而不考虑准备处理什么类型的文件。图4.5显示了通过对话框打开图像文件而不是文本文件时的问题结果。
图4.5 如果用户选择非文本文件,函数将记录二进制数据。
许多桌面应用程序可以限制用户可以打开的文件类型,这也适用于用Electron构建的应用程序。我们的应用程序不适合打开音乐文件,所以我们可能不应该让用户选择mp3。可以将其他选项添加到传递给dialog.showOpenDialog()的配置对象中,以将对话框限制为我们白名单中的文件扩展名。
列表4.5 白名单特定的文件类型: ./app/main.js
const getFileFromUser = exports.getFileFromUser = () => { const files = dialog.showOpenDialog({ properties: ['openFile'], filters: [ //filters属性允许我们指定应用程序应该能够打开那些类型的文件,并禁止不符合我们标准的任何文件。 { name: 'Text Files', extensions: ['txt'] }, { name: 'Markdown Files', extensions: ['md', 'markdown'] } ] }); if (!files) { return; } const file = files[0]; const content = fs.readFileSync(file).toString(); console.log(content); };在清单中,我们向传递给dialog.showOpenDialog()的对象添加了第二个属性。在Windows中,对话框在下拉框中Markdown文件的名称,如图4.6所示。在macOS中,没有下拉菜单,但是我们不能选择没有任何扩展的图像,如图4.7所示。
在macOS中实现对话表