简单文件管理系统

发布时间 2024-01-05 15:57:52作者: SRIGT

0x01 任务要求

  • 根据文件系统的相关原理,设计并用 VC/Java/Python 编程实现一个类似 Windows 系统中“我的电脑”功能的文件管理系统,该文件系统可以对系统中所有文件进行管理,同时具有创建新文件、删除文件、复制文件、创建文件夹等功能。

0x02 需求分析

  • 一个简单的文件管理系统需要具备以下核心功能,以确保用户能够有效地管理他们的文件:

    1. 文件创建:用户应当能够创建新的文件。这包括为他们选择一个文件名和类型。有了这个功能,用户可以轻松地开始一个新的文档或项目。
    2. 文件删除:随着文件的增多,用户可能会想要删除不再需要的文件。因此,该系统必须允许用户选择并删除这些文件。
    3. 文件复制:用户经常需要复制文件以进行备份或其他目的。为此,系统应提供复制功能,并自动为复制的文件生成一个新的名称,以避免与原始文件发生冲突。
    4. 文件夹创建:为了更好地组织文件,用户应该能够创建新的文件夹,并为它们指定名称。这样,用户可以创建多个层次结构来管理他们的文件。
  • 除了这些核心功能外,为了提高用户的体验,系统还可以考虑以下扩展功能:

    1. 文件搜索:随着文件的增多,用户可能很难找到特定的文件。因此,系统应提供搜索功能,使用户能够根据文件名快速找到他们需要的文件。
    2. 文件读取:允许用户打开并查看已存在的文件内容是非常重要的。这不仅使他们能够了解文件的内容,还使他们能够查看文件的详细属性,如创建日期、修改日期等。
    3. 文件写入和覆写编辑:用户经常需要编辑现有的文件。为此,系统应提供写入和编辑功能,允许他们修改文件内容并保存更改。
    4. 文件重命名:有时,用户可能想要更改文件的名称以反映其内容的更改或组织结构的变化。为此,系统应提供重命名功能。
    5. 文件属性修改:除了名称外,文件还有其他属性,如类型、大小等。用户可能需要修改这些属性来更好地组织他们的文件。
    6. 文件夹打开:用户应该能够打开多层级的文件夹以深入到他们的文件结构中。
    7. 文件夹搜索:与文件搜索类似,用户可能希望根据名称或其他属性快速找到特定的文件夹。
    8. 文件夹显示:为了更好地了解文件夹的内容,用户应该能够查看当前文件夹中的所有文件和子文件夹的名称。
    9. 文件夹删除:当用户想要清理不再需要的文件夹及其内容时,他们应该能够删除整个文件夹结构。
    10. 文件夹重命名:与单个文件的重命名类似,用户可能希望更改文件夹的名称以反映其内容的更改或组织结构的变化。

0x03 架构设计

  • 系统整体架构包括文件夹和文件两个主要组件,它们通过父子关系进行组织。

  • 文件夹类用于组织和管理文件。为了实现文件夹的功能,它需要一些私有成员变量来存储和跟踪相关的信息。以下是文件夹类所具有的一些私有成员变量:

    public class Folder {
        private Folder parent;
        private String name;
        private ArrayList<Folder> children;
        private ArrayList<File> files;
    }
    
    1. 指向父文件夹的引用parent:每个文件夹通常都位于一个目录结构中,并有一个父文件夹。这个私有成员变量允许文件夹对象跟踪其父文件夹,以便能够轻松地导航到上级目录。
    2. 表示文件夹名称的字符串name:这是用于标识文件夹的名称的字符串。它是一个私有成员变量,确保名称的唯一性和正确性。通过这个变量,可以获取或设置文件夹的名称,以方便用户识别和管理。
    3. 表示子文件夹的列表children:文件夹类需要一个列表来存储其直接子文件夹。这个列表允许文件夹对象跟踪和管理其下的子文件夹,进行创建、删除、查找等操作。
    4. 表示文件夹中文件的列表files:与子文件夹类似,文件夹还需要一个列表来存储其中的文件。这个列表使得文件夹对象能够跟踪和管理其中的文件,以便进行读取、写入、删除等操作。
  • 文件类用于表示和操作具体的文件。为了实现文件的各种功能,文件类需要包含一系列的私有成员变量来存储和管理文件的相关信息。以下是文件类通常具有的一些私有成员变量:

    public class File {
        private String name;
        private String type;
        private Integer size;
        private String content;
        private Date create_time;
        private Date update_time;
    }
    
    1. 表示文件名称的字符串name:这是一个私有成员变量,用于存储文件的名称。文件名是用户在创建或重命名文件时指定的,它是文件的唯一标识符之一。通过这个变量,可以获取或设置文件的名称,以便在文件系统中进行识别和操作。
    2. 表示文件类型的字符串type:文件类型指示了文件的种类,例如文本文件、图像文件、音频文件等。这个私有成员变量用于存储文件的类型信息,它有助于系统正确地处理不同类型的文件,并提供适当的操作和功能。
    3. 表示文件大小的整型对象size:文件大小是一个关键属性,它指示了文件在磁盘上所占用的空间大小。这个私有成员变量以整型对象的形式存储文件的大小。通过它,可以获取或设置文件的大小信息,以便进行空间管理和性能优化。
    4. 表示文件内容的字符串content:文件的主要目的是存储和传输数据,而这个私有成员变量就是用来存储实际文件内容的。它可以是一个字符串或其他适当的数据结构,取决于文件类型和内容的复杂性。通过这个变量,可以读取、写入文件的内容,以满足用户的需求。
    5. 表示文件创建时间的Date类对象create_time:这个私有成员变量记录了文件的创建时间,即文件首次被创建或保存的时间点。它通常是一个Date类的实例,提供了对日期和时间操作的封装。通过这个变量,可以获取文件的创建时间信息。
    6. 表示修改时间的Date类对象update_time:与创建时间类似,这个私有成员变量用于记录文件的最后修改时间。每次对文件内容进行修改时,这个变量都会被更新为当前的时间戳。通过这个变量,可以追踪文件的修改历史,并确定文件的最新状态。

0x04 关键实现

  1. show()函数的作用是在控制台上显示当前文件夹的内容,包括当前目录、文件夹列表和文件列表。它通过调用 getCurrentDirectory() 方法获取当前目录,然后遍历文件夹和文件列表,将它们的名称逐个打印出来。

    public void show() {
        System.out.print("当前目录:");
        System.out.println(this.getCurrentDirectory());
    
        System.out.print("文件夹:");
        for (Folder folder : this.getChildren()) {
            System.out.print(folder.getName() + " ");
        }
        System.out.println();
    
        System.out.print("文件:");
        for (File file : this.getFiles()) {
            System.out.print(file.getName() + "." + file.getType() + " ");
        }
        System.out.println();
    }
    
  2. openFolder() 函数的作用是打开指定名称的文件夹。如果找到了对应名称的文件夹,则返回该文件夹;如果未找到,则打印消息提示文件夹不存在,并返回当前文件夹。实现方法是通过调用 selectFolder() 函数来查找指定名称的文件夹,如果找到则返回该文件夹,否则打印提示信息并返回当前文件夹。

    public Folder openFolder(String name) {
        Folder result = this.selectFolder(name);
        if (result != null) {
            return result;
        }
        System.out.println("文件夹" + name + "不存在,打开失败!");
        return this;
    }
    
  3. createFolder() 函数的作用是在当前文件夹中创建一个新的子文件夹。实现方法是通过创建一个新的 Folder 对象,并将其添加到当前文件夹的子文件夹列表中。

    public void createFolder(String name) {
        if (this.selectFolder(name) != null) {
            System.out.println("文件夹" + name + "已存在,无法新建!");
            return;
        }
        Folder folder = new Folder();
        folder.setParent(this);
        folder.setName(name);
        this.children.add(folder);
        System.out.println("新文件夹 " + name + " 新建成功");
    }
    
  4. renameFolder() 函数的作用是重命名文件夹。它接受两个参数,分别是旧文件夹名称和新文件夹名称。在实现上,它首先通过旧名称查找文件夹,然后检查新名称是否已存在,如果不存在则将文件夹重命名为新名称,否则输出重命名失败的信息。

    public void renameFolder(String oldName, String newName) {
        Folder result_old = this.selectFolder(oldName);
        if (result_old == null) {
            System.out.println("文件夹" + oldName + "不存在,重命名失败!");
            return;
        }
        Folder result_new = this.selectFolder(newName);
        if (result_new != null) {
            System.out.println("文件夹" + oldName + "已存在,重命名失败!");
            return;
        }
        result_old.setName(newName);
        System.out.println("文件夹" + oldName + "已成功重命名为" + newName);
    }
    
  5. deleteFolder() 函数的作用是删除指定名称的文件夹。如果文件夹存在子文件或子文件夹,函数会提示用户确认是否删除,并根据用户选择执行删除操作或取消删除操作。如果文件夹不存在或删除操作被取消,函数会相应地输出提示信息。

    public void deleteFolder(String name) {
        Folder result = this.selectFolder(name);
        if (result == null) {
            System.out.println("文件夹" + name + "不存在,删除失败!");
            return;
        }
        if (result.children.size() != 0 || result.files.size() != 0) {
            System.out.print("文件夹" + name + "中存在文件/文件夹,删除该文件夹后其中文件无法保留,是否继续删除(y/n):");
            Scanner scanner = new Scanner(System.in);
            String choice = scanner.next();
            if (choice.charAt(0) == 'n') {
                System.out.println("删除取消!");
                return;
            }
            System.out.println("已确认,正在删除...");
        }
        this.children.remove(result);
        System.out.println("文件夹" + name + "已成功删除!");
    }
    
  6. showFile() 函数的作用是查看特定文件的详情。它通过接收文件名和类型作为参数,然后在当前文件夹中查找对应的文件,并显示其详细信息。具体实现方法是通过调用 selectFile() 函数来查找文件,然后显示文件的详细信息。

    public void showFile(String name, String type) {
        File file = this.selectFile(name, type);
        if (file == null) {
            System.out.println("文件" + name + "." + type + "不存在!");
            return;
        }
        file.details();
    }
    
  7. createFile() 函数的作用是创建一个新的文件。它首先检查是否已经存在同名的文件,如果存在则打印消息并返回,否则创建一个新的文件对象,设置文件名和类型,然后将其添加到文件列表中。最后打印新建成功的消息。

    public void createFile(String name, String type) {
        File result = this.selectFile(name, type);
        if (result != null) {
            System.out.println("文件" + name + "." + type + "已存在!");
            return;
        }
        File file = new File();
        file.setName(name);
        file.setType(type);
        this.files.add(file);
        System.out.println("文件" + name + "." + type + "新建成功!");
    }
    
  8. renameFile() 函数的作用是重命名文件。它接受三个参数:旧文件名、新文件名和文件类型。在实现上,它首先查找旧文件名和文件类型是否存在,然后检查新文件名和文件类型是否已存在。如果一切正常,它会将旧文件名修改为新文件名,并更新文件的修改时间。

    public void renameFile(String oldName, String newName, String type) {
        File result_old = this.selectFile(oldName, type);
        if (result_old == null) {
            System.out.println("文件" + oldName + "." + type + "不存在!");
            return;
        }
        File result_new = this.selectFile(newName, type);
        if (result_new != null) {
            System.out.println("文件" + newName + "." + type + "已存在!");
            return;
        }
        result_old.setName(newName);
        result_old.setUpdate_time(new Date());
        System.out.println("文件" + oldName + "." + type + "已成功修改为" + newName + "." + type);
    }
    
  9. retypeFile() 函数的作用是修改文件的类型。它接受三个参数:原文件类型,新文件类型,文件名。函数首先查找是否存在指定名称和原类型的文件,如果存在则将其类型修改为新类型。如果不存在同名的新类型文件,则修改成功并更新文件的修改时间。

    public void retypeFile(String oldType, String newType, String name) {
        File result_old = this.selectFile(name, oldType);
        if (result_old == null) {
            System.out.println("文件" + name + "." + oldType + "不存在!");
            return;
        }
        File result_new = this.selectFile(name, newType);
        if (result_new != null) {
            System.out.println("文件" + name + "." + newType + "已存在!");
            return;
        }
        result_old.setType(newType);
        result_old.setUpdate_time(new Date());
        System.out.println("文件" + name + "." + oldType + "已成功修改为" + name + "." + newType);
    }
    
  10. deleteFile() 函数的作用是删除指定名称和类型的文件。它首先根据给定的文件名和类型查找文件,然后将其从文件列表中移除。如果文件不存在,则会输出相应的错误信息。实现方法包括查找文件、从文件列表中移除文件,并输出相应的成功或失败信息。

    public void deleteFile(String name, String type) {
        File result = this.selectFile(name, type);
        if (result == null) {
            System.out.println("文件" + name + "." + type + "不存在!");
            return;
        }
        this.files.remove(result);
        System.out.println("文件" + name + "." + type + "已成功删除!");
    }
    
  11. copyFile() 函数的作用是复制文件。它接受文件名和类型作为参数,然后在当前文件夹中查找是否存在相同名称的文件,如果存在,则在文件名后加上括号和数字的形式进行复制。复制的文件将具有新的名称,但内容和类型与原文件相同。

    public void copyFile(String name, String type) {
        File result = this.selectFile(name, type);
        if (result == null) {
            System.out.println("文件" + name + "." + type + "不存在!");
            return;
        }
        for (int i = 1; ; i++) {
            String newName = name + "(" + i + ")";
            if (this.selectFile(newName, type)==null) {
                File file = new File();
                file.setName(newName);
                file.setType(type);
                file.setSize(result.getSize());
                file.setContent(result.getContent());
                this.files.add(file);
                System.out.println("文件" + name + "." + type + "复制结果为" + newName + "." + type);
                return;
            }
        }
    }
    
  12. editFile() 函数的作用是编辑文件内容。它会根据给定的文件名和类型,查找文件并允许用户输入新的文件内容,然后将新内容保存到文件中。这个函数只支持单行字符串的覆写操作。

    public void editFile(String name, String type) {
        File result = this.selectFile(name, type);
        if (result == null) {
            System.out.println("文件" + name + "." + type + "不存在!");
            return;
        }
        System.out.println("原文件内容:" + result.getContent());
        System.out.println("**********警告:编辑文件仅支持单行字符串覆写操作**********");
        System.out.print("输入新内容:");
        Scanner scanner = new Scanner(System.in);
        String content = scanner.nextLine();
        System.out.println("保存中...");
        result.setContent(content);
        result.setSize(content.length());
        result.setUpdate_time(new Date());
        System.out.println("文件" + name + "." + type + "已成功写入以下内容:" + content);
    }
    

0x05 完整项目

可以在 GitHub 中下载完整源代码