9

从零开始的electron开发-文件处理-本地文件加载

 4 years ago
source link: https://segmentfault.com/a/1190000040174074
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

文件处理-本地文件加载

我们在使用electron时,有时会涉及一些文件的处理,比如文件的下载,或者本地文件的加载(本地音乐,本地图片等),本章主要介绍electron本地文件的加载。
其实这个功能还是比较常见的,比如我们下载了某某皮肤主题本地,想在本地加载,或者是做一个音乐播放器,加载本地音乐进行播放。
目标:使用input file获取图片或者音乐文件的本地地址(当然你可以直接用已有文件的本地地址),进行展示和播放。

web本地文件加载

浏览器为了安全考虑,在web页面进行文件加载时,是禁用了file://协议进行文件展示的,一般来说要想获取本地文件展示,得让用户进行input file选择,获取File对象,对这个File对象进行操作展示:

<a-upload
  :customRequest="customRequest"
  name="file"
  :showUploadList="false"
  :multiple="true"
>
  <a-button>
    <upload-outlined></upload-outlined>
    添加图片
  </a-button>
</a-upload>
<a-image
  :width="200"
  :height="200"
  :src="state.image"
  />


function customRequest(fileData) {
  const file = fileData.file
  state.image = window.URL.createObjectURL(file)
  // 或者:
   if (file) {
    var reader = new FileReader()
    reader.onload = function (evt) {
      state.image = evt.target.result
    }
    reader.onerror = function (evt) {
      console.error(evt)
    }
    reader.readAsDataURL(file)
  }
}

比如在进行图片的本地显示时,使用createObjectURL直接创建url对象进行展示或者使用readAsDataURL将其转化为base64进行展示。
当然在electron中一切都变得简单起来,我们可以使用本地路径加载文件,当然得进行一些小处理。

electron本地文件加载

比如说我们已知一个本地图片的路径,假设这个路径为下载文件夹中C:\Users\Administrator\Downloads\1.png,我们将这个地址赋值给img的src:

<a-upload
  :customRequest="customRequest"
  name="file"
  :showUploadList="false"
  :multiple="true"
>
  <a-button>
    <upload-outlined></upload-outlined>
    添加图片
  </a-button>
</a-upload>

<a-image
  :width="200"
  :height="200"
  :src="state.image"
  />

function customRequest(fileData) {
  const path = fileData.file.path
  state.image = path
}

这里的path就是本地文件的地址,当你赋值之后发现图片并不能加载,会报一个net::ERR_UNKNOWN_URL_SCHEME的错误,这是由于直接添加本地路径的话,加载文件实际上是通过file://协议进行加载的,默认情况下chromium并不能通过file://协议来读取文件,参考链接, 故并不能直接显示出来,本来可以设置chromium启动参数
(–-allow-file-access-from-files)来解决这个问题,但是比较遗憾electron并不吃这个一套:

// 无效
app.commandLine.appendSwitch('allow-file-access-from-files', true)

我们需要对这个本地路径进行处理,让其不通过file://协议加载,那么如何实现呢?
我们可以通过protocol模块来注册自定义协议并拦截现有协议请求,比如我们实现一个atom://协议加载音乐文件进行播放:

主进程:
app.whenReady().then(() => {
  // 这个需要在app.ready触发之后使用
  protocol.registerFileProtocol('atom', (request, callback) => {
    const url = request.url.substr(7)
    callback(decodeURI(path.normalize(url)))
  })
})

渲染进程:
<a-upload
  :customRequest="customRequest"
  name="file"
  :showUploadList="false"
  :multiple="true"
>
  <a-button>
    <upload-outlined></upload-outlined>
    添加本地音乐
  </a-button>
</a-upload>
<audio :src="state.audio" controls>
</audio>


function customRequest(fileData) {
  const path = 'atom:///' + fileData.file.path
  state.audio = path
}

原来呢我们是直接赋值类似于C:\Users\Administrator\Downloads\1.png,我们在这个路径上加上atom:///变为atom:///C:\Users\Administrator\Downloads\1.png(mac同理,atom是一样的),当匹配到atom时,就会拦截这个协议请求,返回一个本地路径。这里需要注意的一点是如果我们的路径有中文名,那么获取的url是encodeURI编码后的,我们在callback回调时需要用decodeURI进行解码。

注册了自定义协议之后,我们只需在加载本地路径时,在前面加上atom:///(其他名也可,自定义)即可。

本系列更新只有利用周末和下班时间整理,比较多的内容的话更新会比较慢,希望能对你有所帮助,请多多star或点赞收藏支持一下

本文地址:链接
本文github地址:链接


Recommend

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK