简易文件系统-用Go语言从零开始设计(二) 文件目录功能

目录

 

一、文件结构

二、查看文件夹

三、创建文件夹

四、重命名文件夹 删除文件夹

 


一、文件结构

文件结构使用多叉树,新建文件夹只是在数据库记录是一个虚拟的概念,新建文件夹则上传数据并记录在数据库中,并让对应的文件夹的子节点放入该文件。

在服务器代码中文件夹的结构和多叉树的构建如下:

type File struct {
	FileId            string
	FileMd5           string `json:"Md5" form:"Md5"`
	FileName          string `json:"Name" form:"Name"`
	FilePath          string
	FileType          int //0文件 1文件夹
	FileSize          int
	FileNode          []*File
	FileStatus        bool `json:"Status" form:"Status"`
	FileCreateTime    string
	FileLastNode      *File
	Userid            string
	FileVirtualDataId string
}

func NewFile() *File {
	f := new(File)
	f.FileNode = make([]*File, 0)
	f.FileLastNode = nil
	return f
}

// 返回路径目录文件夹 NodefFile 根目录文件指针
func ReturnPathFolder(path string, NodeFile *File) (*File, error) {
	fmt.Println(path)
	if path == "/" {
		return NodeFile, nil
	}
	p := strings.Split(path, "/")
	g := make([]string, 0)
	for i := 0; i < len(p); i++ {
		if p[i] != "" {
			g = append(g, p[i])
		}
	}
	return FindFolder(g, NodeFile)
}

func FindFolder(path []string, NodeFile *File) (*File, error) {
	if len(path) == 0 {
		return NodeFile, nil
	}
	k := NodeFile.FileNode
	for i := 0; i < len(k); i++ {
		if k[i].FileType == 1 && k[i].FileName == path[0] {
			return FindFolder(path[1:], k[i])
		}
	}
	return nil, fmt.Errorf("路径出错%v", path)
}

// 建立文件多叉树
func CreateFileTree(mapfile map[string]*File.File, mapfile1 map[string]*Filedata, firstnode *File.File) {
	if firstnode == nil {
		return
	}
	if firstnode.FileType == 1 {
		// 查找文件夹文件
		file, err := mapfile1[firstnode.FileId]
		if !err {
			fmt.Println("没找到文件", firstnode.FileId)
			return
		}
		filesid := file.NextNodeId
		for _, k := range filesid {
			if k == "" {
				continue
			}
			f1, exit := mapfile[k]
			if !exit {
				fmt.Println("没找到文件1", firstnode.FileId)
				return
			}
			firstnode.FileNode = append(firstnode.FileNode, f1)
			f1.FileLastNode = firstnode
			// 递归
			CreateFileTree(mapfile, mapfile1, f1)
		}
	}
}

 

 

二、查看文件夹

查看文件夹只需要获取该文件夹的子节点信息即可

// 获取文件夹
func RefreshFolder(path string, Tcpconn *TcpConn) error {
	var err error
	BaseNode, exit := UserFileMap[Tcpconn.Id]
	if !exit {
		BaseNode, err = BuildUserFileList(Tcpconn.Id)
		if err != nil {
			fmt.Println(err)
			return err
		}
		UserFileMap[Tcpconn.Id] = BaseNode
	}
	//fmt.Println(BaseNode)
	if BaseNode == nil {
		fmt.Println("根目录指针为空")
		return fmt.Errorf("根目录指针为空")
	}
	file, err := File.ReturnPathFolder(path, BaseNode)
	if err != nil {
		fmt.Println(err)
		return err
	}
	fmt.Println(file)
	// 获取文件里面的信息
	files := GetFileData(file)
	clientfile := make([]ClientFileData, 0)
	for _, f := range files {
		fmt.Println(f)
		clientfile = append(clientfile, FileDataToClientFileData(f))
	}
	var folderdata Folderdata
	folderdata.Path = path
	folderdata.Files = clientfile
	bytes, err := json.Marshal(folderdata)
	if err != nil {
		return err
	}
	var Senddata Data
	Senddata.DataType = "RefreshFolder"
	Senddata.Data = string(bytes)
	bytes, err = json.Marshal(Senddata)
	if err != nil {
		return err
	}
	Tcpconn.WriteMsg(bytes)
	return nil
}


// 获取文件里面的信息
func GetFileData(node *File.File) []Filedata {
	filedatas := make([]Filedata, 0)
	if node.FileType == 0 {
		return filedatas
	}
	for i := 0; i < len(node.FileNode); i++ {
		filedatas = append(filedatas, *(FileToFileData(node.FileNode[i])))
	}
	return filedatas
}

三、创建文件夹

创建文件夹也就是在其上层文件夹中添加该文件夹信息即可

四、重命名文件夹 删除文件夹

重命名文件夹,在本系统的设计当中需要更改其以及文件夹子节点所有目录

比如更改了2311232的名字,需要更改其他目录为/xxxxxx/,需要一个递归进行修改

删除文件夹也是递归进行删除

// 重命名文件夹
func RenameFolder(file Filedata, Userid string) error {
	filedata, err := msql.ReadFileData(file.FileId)
	if err != nil {
		fmt.Println(err)
		return err
	}

	if filedata == nil {
		fmt.Println("未找到该文件")
		return fmt.Errorf("未找到该文件")
	}

	//判断用户文件路径树书否存在  不存在则读取mysql生成
	f, exit := UserFileMap[Userid]
	if !exit {
		f, err = BuildUserFileList(Userid)
		if err != nil {
			fmt.Println(err)
			return err
		}
		UserFileMap[Userid] = f
	}
	// 获取上级目录
	LastFile, err := File.ReturnPathFolder(filedata.Path, f)
	if err != nil {
		fmt.Println(err)
		return err
	}

	// 获取当前指针
	var CurrentFile *File.File
	for i := 0; i < len(LastFile.FileNode); i++ {
		if LastFile.FileNode[i].FileId == file.FileId {
			CurrentFile = LastFile.FileNode[i]
			break
		}
	}
	if CurrentFile == nil {
		fmt.Println("没有找到自身指针")
		return fmt.Errorf("没找到自身指针")
	}

	// 修改当前内容
	CurrentFile.FileName = file.Name
	// 数据库更新
	err = msql.FileDataUpdate(*FileToFileData(CurrentFile))
	if err != nil {
		fmt.Println(err)
		return err
	}
	UpdateFilePath(CurrentFile)
	return nil
}

// 递归修改文件路径
func UpdateFilePath(f *File.File) {
	if f.FileType == 1 {
		for i := 0; i < len(f.FileNode); i++ {
			f.FileNode[i].FilePath = f.FilePath + f.FileName + "/"
			err := msql.FileDataUpdate(*FileToFileData(f.FileNode[i]))
			if err != nil {
				fmt.Println(err)
				return
			}
			UpdateFilePath(f.FileNode[i])
		}
	}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值