【Electron】如何读取拖拽文件数据

1,012 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第6天,点击查看活动详情

一、前言

文章背景为在electron中即时通讯功能有拖拽发送多文件的功能,因为不同类型文件展示不同样式,因此需要读取拖拽至应用内的文件数量以及数据信息。本篇文章主要讲述如何通过js和node读取拖拽至electron应用中的多文件内容数据。

二、实现方式

当前环境为electron11 + vue。

1. 获取文件信息

通过监听drop事件,来获取文件信息

// 拖拽发送文件处理
dragFiles () {
    // 可拖拽释放文件区域
    const dragModel = document.querySelector('.drag-model')
    // 绑定拖拽结束事件
    this.$addEventListener(dragModel, 'drop', (e) => {
        // 必须要阻止拖拽的默认事件
        e.preventDefault()
        e.stopPropagation()
        // 获得拖拽的文件集合
        var files = Array.from(e.dataTransfer.files)
        // 获取所有文件的本地路径
        const list = files.map((item) => {
          return item.path
        })
        // 获取所有文件的信息
        this.getLocalFileInfo(list)
    })
}

2.通过本地文件路径获取文件实例

这里主要通过fs.readFile来读取文件信息,根据文件的类型不同,进行不同的数据处理。

getLocalFileInfo (list) {
  list.forEach((filePath) => {
    const stats = fs.statSync(filePath)
    if (stats.isDirectory()) {
      this.$Message.warning('暂不支持发送文件夹')
      return
    }
    if (stats.size > 100 * 1024 * 1024) {
      this.$Message.error('暂不支持100M以上大小文件发送')
      return
    }
    let fileName = ''
    // 这里要根据windows和mac的系统目录间隔不同进行处理,获取得到文件名
    if (this.$isMac) {
      const index = filePath.lastIndexOf('/')
      fileName = filePath.substring(index + 1)
    } else {
      const index = filePath.lastIndexOf('\\')
      fileName = filePath.substring(index + 1)
    }
    // 设置常用图片类型常量
    const imgType = ['png', 'jpg', 'jpeg', 'gif']
    // 设置常用视频类型常量
    const videoType = ['mp4', 'ogg', 'mov']
    // 获取文件类型的方法
    const getFileType = (str) => {
      return str.substring(str.lastIndexOf('.') + 1)
    }
    // eslint-disable-next-line handle-callback-err
    fs.readFile(filePath, (err, data) => {
      // feat:最大支持发送200M文件
      console.log(data)
      let fileTemp = '' // 最终的文件数据
      if (imgType.includes(getFileType(filePath).toLowerCase())) {
        if (data.byteLength > 10000000) {
          // 图片大于10M当文件上传
          fileTemp = new File([data], fileName, {
            type: 'text/plain',
            path: filePath
          })
        } else {
          // 判断是图片类型文件
          fileTemp = new File([data], fileName, {
            type: 'image',
            path: filePath
          })
        }
      } else if (videoType.includes(getFileType(filePath).toLowerCase())) {
        fileTemp = new File([data], fileName, {
          type: 'video',
          path: filePath
        })
        /* buffer->arrayBuffer */
        const arraybuffer = this.toArrayBuffer(data)
        // console.log(arraybuffer, 'arraybuffer')
        /* arrayBuffer-> blob */
        const blob = new Blob([arraybuffer])
        // console.log(blob, 'blob')
        var url = URL.createObjectURL(blob)
        // console.log(url, 'url')
      } else {
        console.log(data)
        fileTemp = new File([data], fileName, {
          type: 'text/plain',
          path: filePath
        })
      }
      // 这里我们就得到了当前文件的信息
      console.log(fileTemp)         
    })
  })
}

这里是上面使用的 buffer转ArrayBuffer 的方法

toArrayBuffer (buf) {
  var ab = new ArrayBuffer(buf.length)
  var view = new Uint8Array(ab)
  for (var i = 0; i < buf.length; ++i) {
    view[i] = buf[i]
  }
  return ab
}

综上 我们就获取得到了拖拽模版上所有的文件信息。就可以进行接下来的操作了,比如处理发送文件等等功能。

三、后记

这里在electron的渲染进程中可以使用node的方法极大地拓展了前端广度,很多之前不能做或者不好做的东西,可以尝试着用node去实现了。后面会给大家讲解如何获取剪切板上的文件信息。

本篇完结! 撒花! 感谢观看!希望能帮助到你!