文件系统设计 - 开发文件系统 Store (上篇)

本节开始,我们将从最核心基础的文件系统进行设计实现,构建文件系统Store

  • 一个基础的响应式Store类
  • 设计文件系统类接口
  • 小结

一个基础的响应式Store类

Vue3 开始,Vue响应式借助Proxy重构后,整个响应式系统的应用变得非常的灵活,虽然目前业界依旧有 Pinia 等响应式管理库,但其本质依旧是在借助Vue的响应式API进行设计实现;所以很多时候其实并非需要第三方的响应式管理库,如果只是简单的响应式处理直接借助 Vue 的响应式API即可。

关于Vue3 的响应式实现细节,大家可以参考网上很多的Vue原理解析文章,或者大家有兴趣可以在下方留言,后面也可以出一期从0手写mini-vue3 源码的专栏

这里我们便借助 Vue 的响应式API封装一个具有响应式State管理的基类

import { reactive, UnwrapNestedRefs } from 'vue'export abstract class Store<T extends Record<string, unknown>> {state: UnwrapNestedRefs<T>;constructor(state: T) {this.state = reactive(state);}
}

设计文件系统类接口

web端的编辑器虽然可以借助 File System Access API 对本地文件进行操作,但是因其兼容性问题,目前Web编辑器的文件还是存在内存中的,将文件以树型结构在内存中进行存储维护,所以首先我们先明确文件系统的主要作用是: 管理内存中的文件树; 这里的管理主要包括以下部分:

  • 创建文件/文件夹
  • 删除文件/文件夹
  • 查找文件/文件夹
  • 移动文件/文件夹
  • 文件/文件夹重命名
  • 文件写入

首先,我们需要先设计出文件在内存中进行管理的数据结构定义

// 定义文件的类型
export const enum FileType {File,Directory,
}// 文件的结构定义
export interface IFileSystemItem {filename: string;  	/* 文件名 */type: FileType.File; 	/* 文件类型 */code: string;			/* 文件的代码 */ext: string;			/* 文件的扩展名 */fullPath: string;		/* 文件的完整路径 */status: number;		/* 文件当前的状态: 用于记录当前对文件的操作 */cacheBuffer: string | null  /** 文件内容缓冲区 */;language?: string;	/* 代码语言 */readonly?: boolean;	/* 文件是否只读 */visible?: boolean;	/* 文件是否在文件树中显示 */
}// 目录的结构定义
export interface IDirectoryItem extends Record<string, unknown> {filename: string; 			/* 文件名 */type: FileType.Directory;		/* 文件类型 */fullPath: string;				/* 文件完整路径 */status: number;				/* 文件夹当前状态 */readonly?: boolean;			/* 文件夹是否只读 */visible?: boolean;			/* 文件夹是否在文件树中可见 */children: (IFileSystemItem | IDirectoryItem)[];	/* 文件夹下的子文件 */
}

定义好文件系统在内存中的存储结构后,我们还需要定义文件系统的响应式 State 中的数据结构

export type FileSystemState = {/* 文件树 - 单根文件夹 */files: IDirectoryItem;/* 文件Map映射,方便快速的根据文件路径查找文件 */fileMap: Map<string, IFileSystemItem | IDirectoryItem>;
};

对于文件的操作,我们将通过文件的 status 字段进行记录,比如文件编辑、文件重命名等;那如何通过一个字段来记录多种状态呢? 这里我们采用二进制位Mask来处理,首先我们先定义几个基础的文件操作:

export const enum FileOperation {Editing = 0b00000001,Rename = 0b00000010,Delete = 0b00000100,Move = 0b00001000,Create = 0b00010000,
}

关于如何通过二进制位Mask来记录不同的状态,我们将在下篇文章中具体实现文件系统进行介绍

完成以上步骤之后,现在我们可以开始定义文件系统的接口描述了,文件系统Store 是一个继承自响应式基类的文件管理子类,处理响应式文件State 数据之外,还有相关的文件操作逻辑:

export interface FileSystemProvider {/* 响应式的文件数据 */state: FileSystemState;/*** 创建文件* @param path 文件路径 uri* @param content 文件内容* @param readonly 是否只读* @param visible 是否可见*/createFile(path: Uri,content: string,readonly?: boolean,visible?: boolean): IFileSystemItem;/*** 创建目录* @param path 目录 Uri* @param readonly 是否只读* @param visible 是否可见*/createDirectory(path: Uri,readonly?: boolean,visible?: boolean): IDirectoryItem;/*** 读取文件内容* @param path 文件路径 uri*/readFile(path: Uri | string): IFileSystemItem | IDirectoryItem | null;/*** 写入文件数据* @param path 文件路径 uri* @param content 文件内容* @returns 文件变更状态数据*/writeFile(path: Uri | string,content: string,isBuffer?: boolean): ChangeFileState | null;/*** 删除文件或目录* @param file 文件对象* @returns 文件变更状态数据*/delete(file: IFileSystemItem | IDirectoryItem): ChangeFileState | null;/*** 文件重命名* @param file 文件对象* @param newName 文件名* @returns 文件变更状态数据*/renameFile(file: IFileSystemItem, newName: string): ChangeFileState;/*** 文件夹重命名* @param folder 文件对象* @param newName 文件名* @returns 文件变更状态数据*/renameFolder(folder: IDirectoryItem, newName: string): ChangeFileState[];/*** 移动文件* @param sourcePath 源路径* @param targetPath 目标路径* @returns 文件变更状态数据数组*/moveFile: (sourcePath: Uri | string,targetPath: Uri | string) => ChangeFileState[] | null;/*** 为文件对象添加操作* @param file 文件对象* @param operator 操作*/addOperator: (file: IFileSystemItem | IDirectoryItem,operator: FileOperation) => void;/*** 为文件对象移除操作* @param file 文件对象* @param operator 操作*/removeOperator: (file: IFileSystemItem | IDirectoryItem,operator: FileOperation) => void;
}

小结

这一章我们正式开始组件库的开发,组件的开发我认为最重要的不是组件如何渲染,而是数据如何维护和管理;
从这章开始我们介绍的是整个编辑器组件的核心:文件系统; 我们将按照面向接口编程的方式,逐步设计和实现文件系统的管理和操作。这一章节我们通过TS类型定义设计实现了文件系统相关的接口定义,大家也可以根据目前文件系统的接口定义,尝试实现文件系统管理类。

如果大家在开发过程中有任何的问题欢迎下方留言评论,我将尽快为大家解答;加油!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/54477.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

vue2:树形控件el-tree中加载两种不同结构的数据

需求 需要在树形控件中逐级显示公司、部门以及不同部门下的项目信息。其中&#xff0c;公司及部门信息的结构是一致的&#xff0c;但是项目是另一种结构&#xff08;类&#xff09;。所以&#xff0c;树结构中需要用到两种不同结构的数据。 El-tree 主要属性 下面是一个el-…

《ChatGPT:强大的人工智能聊天机器人》

《ChatGPT&#xff1a;强大的人工智能聊天机器人》 一、引言 在当今科技飞速发展的时代&#xff0c;人工智能已经成为了各个领域的热门话题。而 ChatGPT&#xff0c;作为一款强大的人工智能聊天机器人&#xff0c;自推出以来就引起了广泛的关注和热议。它不仅能够进行自然流畅的…

浅谈Spring Cloud:认识微服务

SpringCloud就是分布式微服务架构的一站式解决方案&#xff0c;是微服务架构落地的多种技术的集合。 目录 微服务远程调用 Eureka注册中心 搭建Eureka Server 注册组件 服务拉取 当各种各样的服务越来越多&#xff0c;拆分的也越来越细&#xff0c;此时就会出现一个服务集…

基于mockito做单元测试

1.简介 配合断言使用(杜绝System.out)可重复执行不依赖环境不会对数据产生影响Spring的上下文环境不是必备的一般都配合mock类框架对数据库进行隔离 mock类使用场景&#xff1a; 要进行测试的方法存在外部依赖(DB,Redis,第三方接口),为了专注于对该方法的逻辑进行测试&#…

计算机毕业设计 社区医疗服务系统的设计与实现 Java实战项目 附源码+文档+视频讲解

博主介绍&#xff1a;✌从事软件开发10年之余&#xff0c;专注于Java技术领域、Python人工智能及数据挖掘、小程序项目开发和Android项目开发等。CSDN、掘金、华为云、InfoQ、阿里云等平台优质作者✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精…

国产游戏技术能否引领全球【终稿】

国产游戏技术能否引领全球 摘要&#xff1a;近年来&#xff0c;国产游戏行业蓬勃发展&#xff0c;技术水平不断提升&#xff0c;多款作品在国际市场上崭露头角。从画面渲染到物理引擎&#xff0c;从AI技术到服务器架构&#xff0c;中国游戏开发者在各个领域都取得了显著进步。…

MySQL高阶1919-兴趣相同的朋友

题目 请写一段SQL查询获取到兴趣相同的朋友。用户 x 和 用户 y 是兴趣相同的朋友&#xff0c;需满足下述条件&#xff1a; 用户 x 和 y 是朋友&#xff0c;并且用户 x and y 在同一天内听过相同的歌曲&#xff0c;且数量大于等于三首. 结果表 无需排序 。注意&#xff1a;返…

常见排序(C语言版)

1.排序的概念及其应用 1.1排序的概念 排序&#xff1a;​ 在计算机科学与数学中&#xff0c;一个排序算法&#xff08;英语&#xff1a;Sorting algorithm&#xff09;是一种能将一串资料依照特定排序方式排列的算法。 稳定性&#xff1a;假定在待排序的记录序列中&#xff…

聚观早报 | 小米三折叠手机专利曝光;李斌谈合肥投资蔚来

聚观早报每日整理最值得关注的行业重点事件&#xff0c;帮助大家及时了解最新行业动态&#xff0c;每日读报&#xff0c;就读聚观365资讯简报。 整理丨Cutie 9月20日消息 小米三折叠手机专利曝光 李斌谈合肥投资蔚来 索尼PS5 Pro包装亮相 新一代Spectacles AR眼镜发布 通…

三十种编程语言庆祝【国庆节】!!!

30种编程语言来打印“国庆节快乐”&#xff1a; 分别为&#xff1a; PythonJavaScriptJavaCCC#PHPRubySwiftGoRustKotlinScalaPerlRLuaDartTypeScriptBash (Shell)F#JuliaElixirHaskellGroovyVisual Basic .NETMATLABPowerShellSQLVBA (Visual Basic for Applications)COBOL …

《AI系统:原理与架构》于华为HC大会2024正式发布

2024年9月21日&#xff0c;《AI系统&#xff1a;原理与架构》新书发布会在上海世博馆华为HC大会顺利举办。本书由华为昇腾技术专家、B站AI科普博主ZOMI酱和哈工大软件学院副院长苏统华教授联合编写&#xff0c;是领域内AI系统方面填补空白的重磅之作。 发布会上&#xff0c;《A…

Spring:项目中的统一异常处理和自定义异常

介绍异常的处理方式。在项目中&#xff0c;都会进行自定义异常&#xff0c;并且都是需要配合统一结果返回进行使用。 1.背景引入 &#xff08;1&#xff09;背景介绍 为什么要处理异常&#xff1f;如果不处理项目中的异常信息&#xff0c;前端访问我们后端就是显示访问失败的…

【监控】【Nginx】使用 Zabbix 监控 Nginx,并使用 InfluxDB 存储数据的详细指南

目录 1. 安装 Zabbix Server步骤 1&#xff1a;安装 Zabbix 服务器步骤 2&#xff1a;安装 InfluxDB步骤 3&#xff1a;启动 InfluxDB 服务步骤 4&#xff1a;创建 InfluxDB 数据库步骤 5&#xff1a;配置 Zabbix Server步骤 6&#xff1a;启动 Zabbix 服务 2. 安装 Zabbix Age…

JavaScript发送邮件:实现前端触发的教程?

JavaScript发送邮件的方式&#xff1f;怎么使用JavaScript发信&#xff1f; 无论是用户反馈、联系表单还是自动通知&#xff0c;前端触发的邮件发送功能都能极大地提升用户体验。AokSend将详细介绍如何通过JavaScript发送邮件&#xff0c;实现前端触发的邮件发送功能。 JavaS…

Centos7安装chrome的问题

chrome是129版本的&#xff0c;很新。 启动chrome的时候报错&#xff1a;undefined symbol: ippvalidateattributes 这个没有报libxxx.so not found。 大概就是依赖的so库版本太低了&#xff0c;查了下这个函数在cups 重新拉了最新的代码并编译 ./configure --with-tlsno…

跨站请求伪造(CSRF)漏洞详解

免责申明 本文仅是用于学习检测自己搭建的DVWA靶场环境有关CSRF的原理和攻击实验,请勿用在非法途径上,若将其用于非法目的,所造成的一切后果由您自行承担,产生的一切风险和后果与笔者无关;本文开始前请认真详细学习《‌中华人民共和国网络安全法》‌及其所在国家地区相关法…

ubuntu24安装vivado24(安装并解决若干错误)

目录 安装方法&#xff1a;问题1&#xff1a;解决办法&#xff1a; 问题2&#xff1a;解决方法&#xff1a; 安装完成&#xff1a; 安装方法&#xff1a; 注意&#xff1a;内存最好预留80G空闲的。 安装好大小&#xff1a; 安装依赖库&#xff1a; sudo apt-get update sud…

计算机网络17——IM聊天系统——客户端核心处理类框架搭建

目的 拆开客户端和服务端&#xff0c;使用Qt实现客户端&#xff0c;VS实现服务端 Qt创建项目 Qt文件类型 .pro文件&#xff1a;配置文件&#xff0c;决定了哪些文件参与编译&#xff0c;怎样参与编译 .h .cpp .ui&#xff1a;画图文件 Qt编码方式 Qt使用utf-8作为编码方…

Java 8 和 MyBatis 框架实现每天凌晨 2 点进行增量缓存

以下是使用 Java 8 和 MyBatis 框架实现每天凌晨 2 点进行增量缓存的完整示例代码&#xff1a; Offering 实体类&#xff1a; public class Offering { private String id; private String name; private String size; private String type; // 构造方法、get…

堆栈指针寄存器SP的初值是多少?执行PUSH AX命令后,SP的值是多少?执行POP BX后,SP的值是多少?为什么答案给的是200,202,200。

欢迎来到我的技术博客&#xff01; &#x1f389; 这里不仅有满满的编程干货和学习资源&#xff0c;我的某站账号也为你准备了更多实用的技术视频和知识分享。 &#x1f449; 点击关注我的小破站账号&#xff0c;获取更多编程技巧和学习资源&#xff01; 小破站主页 例题 ST…