【前端】之MEMFS实现简单的文件管理器

7 篇文章 2 订阅
6 篇文章 0 订阅

MEMFS实现简单的文件管理器

使用的是ffmpeg里的fs模块
fs的api可以参考emscripten的文档

上界面

在这里插入图片描述

上代码

<template>
  <div>
    fs文件系统
    <button @click="readDir">读取文件夹</button>
    <input @change="changFile" type="file" id="uploader" placeholder="文件">
    <button @click="saveFile">保存</button>
    <div class="path">
      <button @click="handleRefresh">刷新</button>
      <button @click="handleUpper">返回上一层</button>
      路径:<input v-model="path" placeholder="文件路径" @keyup.enter="handleRefresh"/>
      新建文件夹:<input v-model="newDir" placeholder="新建文件夹"/><button @click="handleMkdir">新建</button>
      新建文件:<input v-model="newFile" placeholder="新建文件"/><button @click="handleMkfile">新建</button>
      <button @click="handleUpload">上传文件</button>
    </div>
    <div class="file-list">
      <div class="file" :class="{active:file.name === active}" v-for="(file,index) in fileList" :key="'file' + index" @click="handleClick(file)" @dblclick="handleDbClick(file)">
        <div class="preview">
        </div>
        <div class="name">{{ file.name }}</div>
        <div class="size">{{ file.size }}</div>
        <div class="type">{{ file.type === fileTypeEnum.FILE?'文件':'文件夹' }}</div>
        <div class="created-date">{{ file.createDate }}</div>
        <div class="action">
          <span @click.stop="rename(file)">重命名</span>|
          <span @click.stop="remove(file)">删除</span>|
          <span v-if="file.type === fileTypeEnum.FILE" @click="download(file)">下载</span>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup>
// 本身项目用了ffmpeg,所以这里使用的是ffmpeg里的FS模块
import { createFFmpeg , fetchFile } from '@ffmpeg/ffmpeg'
import dayjs from 'dayjs'
import { onMounted , ref } from 'vue'
let fs = ''
const fileTypeEnum = {
  FILE:'file',
  DIR:'dir'
}
const path = ref('/')
const newDir = ref('')
const file = ref({})
const newFile = ref('')
const fileList = ref([])
const active = ref('')
onMounted(async () => {
  let ffmpeg = createFFmpeg( {
    log: true
  })
  await ffmpeg.load();
  fs = ffmpeg.FS
  console.log("fs",fs)
  handleRefresh()
})
let tmpFile = ''
const changFile = (file) => {
  console.log("选择文件",file.target.files)
  tmpFile = file.target.files[0]
}
const saveFile = async () => {
  console.log("保存文件",tmpFile)
  fs( 'writeFile' , tmpFile.name , await fetchFile(tmpFile) );
  const data = fs( 'readFile' , tmpFile.name );
  console.log("文件数据",data)
  handleRefresh()
}

const readDir = (path) => {
  const list=fs('readdir',path)
  console.log("文件列表",list)
  // fileList.value = list
  const showList = []
  list.forEach(file => {
    if(file !== '.' && file !== '..'  ){
      const item = {
        name:file,
        type:'',
        size:"",
        createDate:''
      }
      // 获取文件属性
      const info=fs('stat',path + file)
      console.log("info",info)
      item.createDate = dayjs(info.ctime).format('YYYY-MM-DD HH:mm:ss')
      item.size = info.size
      // 判断文件类型
      const isFile=fs('isFile',info.mode + '')
      item.type = isFile?fileTypeEnum.FILE:fileTypeEnum.DIR
      showList.push(item)
    }
  })
  fileList.value = showList
}

const handleRefresh = () => {
  console.log("刷新")
  if(path.value[path.value.length-1] !== '/') {
    path.value += '/'
  }
  readDir(path.value)
}
const handleUpper = () => {
  console.log("返回上一层")
  const pathArr = path.value.split('/')
  if(path.value === '/') {
    console.log("根目录")
    return
  }
  pathArr.splice(pathArr.length-2,1)
  console.log(pathArr.length,pathArr)
  path.value = pathArr.join('/')
  setTimeout(() => {
    handleRefresh()
  },100)
}
const handleMkdir = () => {
  console.log("新建文件夹",newDir.value)
  const data=fs('mkdir',path.value + newDir.value)
  console.log("结果",data)
  handleRefresh()
}
const handleMkfile = () => {
  console.log("新建文件")
  const data=fs('writeFile',path.value+newFile.value,'')
  console.log("结果",data)
  handleRefresh()
}
const handleUpload = () => {
  console.log("上传文件")
  let input = document.createElement('input');
  input.type = 'file';
  input.onchange = e => {
    tmpFile = e.target.files[0];
    console.log("添加的文件",tmpFile)
    saveFile()
    setTimeout(() => {
      handleRefresh()
    },100)
  }
  input.click();

}
const handleClick = (file) => {
  console.log("单机",file)
  active.value = file.name
}
const handleDbClick = (file) => {
  console.log("双击",file)
  if(file.type === fileTypeEnum.DIR) {
    active.value = ''
    path.value =  path.value + file.name + '/'
    setTimeout(() => {
      handleRefresh()
    },100)
  }
  if(file.type === fileTypeEnum.FILE) {
    const data = fs( 'readFile' ,path.value + file );
    console.log("文件数据",data)
  }
}
const download = (file) => {
  console.log("下载",file)
  const data = fs( 'readFile' ,path.value + file.name );
  const blob = new Blob([data])
  console.log("文件数据",data)
  saveAs(blob,file.name)
}
const rename = (file) => {
  console.log("重命名",file)
  const name=prompt("请输入新文件名 :",file.name);
  console.log("新文件名",name)
  const data = fs( 'rename' ,path.value + file.name,path.value + name );
  console.log("重命名",data)
  setTimeout(() => {
    handleRefresh()
  },100)

}

const remove = (file) => {
  console.log("删除",file)
  if(file.type === fileTypeEnum.DIR) {
    const data = fs( 'rmdir' ,path.value + file.name );
    console.log("删除",data)
  }
  if(file.type === fileTypeEnum.FILE) {
    const data = fs( 'unlink' ,path.value + file.name );
    console.log("删除",data)
  }
  setTimeout(() => {
    handleRefresh()
  },100)
}
function saveAs(blob, filename) {
  if (window.navigator.msSaveOrOpenBlob) {
    navigator.msSaveBlob(blob, filename)
  } else {
    const link = document.createElement('a')
    const body = document.querySelector('body')

    link.href = window.URL.createObjectURL(blob)
    console.log('创建的文件名', filename)
    link.download = filename
    link.style.display = 'none'
    body.appendChild(link)
    link.click()
    body.removeChild(link)
    window.URL.revokeObjectURL(link.href)
  }
}

</script>


<style lang="less" scoped>
.file-list{
  height: 500px;
  overflow: auto;
  .file{
    display: flex;
    &:hover{
      background: #eee;
      transition: 0.2s;
    }
    &.active{
      background: #ddd;
    }
    .preview{
      width: 50px;
      text-align: center;
    }
    .name{
      flex: 1;
    }
    .size{
      width: 120px;
    }
    .type{
      width: 80px;
    }
    .created-date{
      width: 150px;
    }
    .action{
      width: 200px;
      >span{
        cursor: pointer;
      }
    }
  }
}


</style>


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
web前端文件管理器是一种用于管理和组织网站的文件和资源的工具。它可以通过图形界面提供简单易用的操作,使开发人员能够轻松地浏览、上传、下载、删除和重命名文件,以及创建、编辑和删除文件夹。 该文件管理器通常具有以下功能和特点: 1. 文件浏览:用户可以通过文件管理器浏览整个网站文件结构,包括文件文件夹。 2. 文件上传和下载:用户可以通过文件管理器上传文件到服务器,也可以从服务器下载文件到本地。 3. 文件删除和重命名:用户可以使用文件管理器删除不需要的文件,也可以重命名文件以提高文件的可读性。 4. 文件夹管理:用户可以在网站中创建、编辑和删除文件夹,以组织和管理文件。 5. 文件编辑:某些文件管理器还提供在线文件编辑功能,例如HTML、CSS、JavaScript等。 6. 权限管理:通过文件管理器,用户可以为文件文件夹设置不同的权限,以控制其他用户对文件的访问、编辑和下载。 7. 多语言支持:文件管理器通常支持多种语言,以适应不同用户的需求。 8. 响应式设计:为了适应不同大小的屏幕,文件管理器通常具有响应式设计,可以在不同设备上自动调整布局和显示效果。 总之,web前端文件管理器是一种非常有用的工具,可以帮助开发人员高效地管理和组织网站的文件和资源。它提供了许多方便的功能,使开发人员能够轻松地处理文件操作,并提供更好的用户体验。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值