IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 系统运维 -> OS实验七【文件管理】 -> 正文阅读

[系统运维]OS实验七【文件管理】

目录

一、实验目的

二、实验内容

三、实验要求

四、设计原理及相关算法

五、结果分析?

1. 编译文件test08.cpp

2. format:格式化命令

3. mkdir hello:创建hello子目录

4. ls hello:显示hello目录下的信息

5. cd hello:进入hello目录

6. create world 100:创建新文件world

7. cp world hello:复制文件wold为文件hello

8. rename hello world2:重命名文件hello为world2

9. rm world:删除world文件

10. rmdir hello:删除hello目录

11. exit:退出该系统并保存消息

六、源代码?


一、实验目的

1、探索、理解并掌握 FAT 文件系统的组织结构、设计原理和编程设计要旨。

2、通过实验,掌握 MSDOS 文件系统中文件目录管理的实现方法。

二、实验内容

1、设计并实现一个用于实现目录列表(类似 DOS 下的 DIR 命令或 Linux Shell 命令 ls)的函数。

2、设计并实现一个用于实现文件更名的函数。

3、设计并实现一个用于实现文件删除的函数。

4*、设计并实现创建新目录、把现有的文件拷贝到新文件的函数。

这些函数的原型如下:

int fd_ls();

int fd_rename(char *oldfilename,char *newfilename);

int fd_rm(char *name);

int fd_mkdir(char *name);

int fd_cp(char *source, char *destination);

三、实验要求

本实验在 MSDOS 格式的软盘上完成。要实现这些函数需要一个使物理磁盘准备的函数(该函 数调用磁盘驱动程序的初始化代码以及选择的其他初始化代码来判断磁盘几何结构): int fd_load(char driveLetter); 文件的更名与删除,需要查找文件,文件删除还要遍历 FAT 中的链接,设置 FAT 中每个簇项并将其标记为未使用,更新目录项。在删除的情况中,要注意文件的隐藏、只读和系统属性。任何具有这种属性的文件都不能删除。

此外,任务 4 中还需要 fd_open()fd_close()fd_read()fd_write()函数实现字节流的写。

四、设计原理及相关算法

想要完成操作系统算法,首先要弄清楚操作系统相关的专业术语。弄清各个算法的流程和目的要求。才能模拟出相关算法的过程。

一般情况下,操作系统中,文件管理提供了如下功能:

①统一管理文件存储空间(即外存),实施存储空间的分配与回收。
②确定文件信息的存放位置及存放形式。
③实现文件从名字空间到外存地址空间的映射,即实现文件的按名存取。
④有效实现对文件的各种控制操作(如建立、撤销、打开、关闭文件等)和存取操作(如读、写、修改、复制、转储等)

其实就是对文件进行管理。

本次实验对文件定义了如下数据结构:

class file:
    def __init__(self, uid, fid, name, status):
        self.uid = uid
        self.fid = fid
        self.name = name
        self.status = status

定义了文件的id标识,文件名,状态等等。

五、结果分析?

1. 编译文件test08.cpp

g++ test08.cpp -o test08

2. format:格式化命令

3. mkdir hello:创建hello子目录

4. ls hello:显示hello目录下的信息

5. cd hello:进入hello目录

6. create world 100:创建新文件world

7. cp world hello:复制文件wold为文件hello

8. rename hello world2:重命名文件hello为world2

9. rm world:删除world文件

10. rmdir hello:删除hello目录

11. exit:退出该系统并保存消息

六、源代码?

创建文件test08.cpp

vim test08.cpp
g++ test08.cpp -o test08
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <string.h>
#include <bitset>

using namespace std;
const int BLOCKNUM_SIZE=2;					//盘块号大小
const int BLOCK_SIZE=1024;				    //一个盘块大小数
const int BLOCK_NUM=10001;				    //盘块数量
const int DISK_SIZE=1024*1000*10;			//磁盘大小
const int LIST_SIZE=32;						//目录项大小
const int MAP_SIZE=10001;						//MAP 长度
const int FATNUM=125;						//FAT的盘块数 第块没有用
const int FATLIST=512;					//每个盘口FAT的记录数
const int DATABEG=128;					//数据项开始FAT号

struct FCB{
    char fname[8];						//文件名
    char exname[3];						//扩展名
    short  fnum;						//首块号
    int length;							//文件大小,  目录则文件大小为;
};

struct fatid{
    short id[FATNUM*FATLIST];   //FAT 大小512个记录 一块
}*FAT;

struct map{
    bitset<MAP_SIZE> maplist;
}*MAP;

struct DIR{
    struct FCB list[LIST_SIZE+1];
}*filedir;

int currentid=128;                  //当前FAT号
int currentdir=128;                 //当前目录块号初始化是+1  由于第个单元没有使用
char *file;                          //磁盘的首地址
char *FilePath="myfat";              //window文件保存地址
FILE *fp;                           //window 文件地址
string CURRENT="root\\";				//当前路径
char  cmd[30];						//输入指令
char command[16];



/*
*对文件存储器进行格式化
*创建根目录
*
*/
void init(struct fatid *FAT){
    int i,j;
    for(i=1;i<FATNUM*FATLIST;i++)			//第块 不使用
    {
        if(i>DATABEG)
            FAT->id[i]=0;
        else
            FAT->id[i]=-1;
    }
}
void format(){
    bool i;
    FAT=(struct fatid *)(file+BLOCK_SIZE);                         //当前FAT地址
    MAP=(struct map *)(file+(FATNUM+1)*BLOCK_SIZE);       //初始化位示图
    init(FAT);
    FAT->id[0]=9872;
    filedir=(struct DIR *)(file+(FATNUM+1+2)*BLOCK_SIZE);		  //当前目录指针地址
    FAT->id[128]=-1;
    FAT->id[0]=9872-1;
    strcpy(filedir->list[0].fname,".");
    strcpy(filedir->list[0].exname,"dir");
    filedir->list[0].fnum=currentdir;
    filedir->list[0].length=0;
    strcpy(filedir->list[1].fname,"..");
    strcpy(filedir->list[1].exname,"dir");
    filedir->list[1].fnum=currentdir;
    filedir->list[1].length=0;
    fp=fopen(FilePath,"w+");
    fwrite(file,sizeof(char),DISK_SIZE,fp);
    fclose(fp);
    printf("初始化已经完成,现在可以进行操作了!\n\n");
}

/*
*创建子目录
*/
int mkdir(char *str)
{
    int i,j;
    int blockid;			//将要创建的FAT号
    int blockdir;			//将要创建的目录块号
    int listnum;			//目录块内编号

    struct fatid *flagid;
    struct DIR *dir;        //当前目录指针
    struct map *MAP;
    struct fatid *FAT;

    if(strcmp(str,"")==0)
    {
        printf("目录名称不能为空\n");
        return 0;
    }

    dir=(struct DIR *)(file+(currentdir)*BLOCK_SIZE);
    MAP=(struct map *)(file+(FATNUM+1)*BLOCK_SIZE);
    FAT=(struct fatid *)(file+BLOCK_SIZE);

    for(i=DATABEG+1;i<BLOCK_NUM;i++)   //从128块数据块 实际上的块开始搜索
        {
        if(MAP->maplist[i]==0)
            break;

        }

    if(i>BLOCK_NUM)
    {
        printf("内存不足\n");
        return 0;
    }

    MAP->maplist[i]=1;				//map 置即已用


    dir=(struct DIR *)(file+(currentdir)*BLOCK_SIZE);


    for(i=2;i<LIST_SIZE;i++)
    {
        if(strcmp(dir->list[i].fname,str)==0)
        {
            printf("目录下有同名文件夹\n");
            return 0;
        }
    }
    for(i=2;i<LIST_SIZE;i++)
    {

        if(strcmp(dir->list[i].fname,"")==0)			//有空的目录块且无重名,第一版本的时候与上面的循环放在一起,存在一个情况是前面的建立的目录删除后,直接被同名的覆盖了
            break;
        if(i>LIST_SIZE)
        {
            printf("内存不足\n");
            return 0;
        }
    }
    flagid=(struct fatid *)(file+BLOCK_SIZE);	//fat 首位地址

    for(j=DATABEG+1;j<BLOCK_NUM;j++)
    {
        if(flagid->id[j]==0)
        {
            blockdir=j;
            break;
        }
    }

    strcpy(dir->list[i].fname,str);
    dir->list[i].fnum=blockdir;
    strcpy(dir->list[i].exname,"dir");
    dir->list[i].length=0;


    dir=(struct DIR *)(file+blockdir*BLOCK_SIZE);   //为新目录项创建根目录
    strcpy(dir->list[0].fname,".");
    strcpy(dir->list[0].exname,"dir");
    dir->list[0].fnum=blockdir;
    dir->list[0].length=0;

    strcpy(dir->list[1].fname,"..");
    strcpy(dir->list[1].exname,"dir");
    dir->list[1].fnum=currentdir;
    dir->list[1].length=0;

    flagid->id[j]=-1;                 //修改FAT  目录尾部
    FAT->id[0]=FAT->id[0]-1;

    printf("已经成功创建目录%s \n",str);

    return 0;
}

/*
*显示目录
*/
int listshow()
{
    int i,sumfile,sumdir,fl[100],dr[100];//fl 为文件的号数,dr为目录的号数
    sumfile=sumdir=0;

    struct DIR *dir;
    struct fatid *FAT;

    dir=(struct DIR *)(file+currentdir*BLOCK_SIZE);

    for(i=0;i<LIST_SIZE;i++)
    {
        if(dir->list[i].length==0&&(strcmp(dir->list[i].fname,"")!=0)&&(dir->list[i].fnum!=0))			//为目录的
            {
            dr[sumdir]=i;
            sumdir++;

            }
        if(dir->list[i].length!=0&&strcmp(dir->list[i].fname,"")!=0)			//为目录的
            {
            fl[sumfile]=i;
            sumfile++;

            }


    }

    for(i=0;i<sumdir;i++)
        printf("   %s       文件夹\n",dir->list[dr[i]].fname);

    for(i=0;i<sumfile;i++)
        printf("   %s       %s文件\n",dir->list[fl[i]].fname,dir->list[fl[i]].exname);

    printf("\n");

    printf("\n在该目录下共有%d 个文件, %d 个文件夹\n\n",sumfile,sumdir-2);
    return 0;
}

/*
*删除子目录
*/
int rmdir(char *str)
{
    int  i;
    int blockid;
    int flag=0;
    //FAT号
    int blocknum;				//目录块

    struct fatid *FAT;
    struct DIR *dir;
    struct DIR *flagdir;		//标记目录块


    char c='a';			   //做用户交互
    int m=2;				//从第三个子目录项开始搜索要删除的目录项情况

    FAT=(struct fatid *)(file+BLOCK_SIZE);
    dir=(struct DIR *)(file+currentdir*BLOCK_SIZE);			//当前目录指针
    MAP=(struct map *)(file+(FATNUM+1)*BLOCK_SIZE);


    for(i=2;i<LIST_SIZE;i++)
    {
        if(strcmp(dir->list[i].fname,str)==0)		//找到要删除的子目录
            {
            break;
            }
    }

    if(i>LIST_SIZE)
    {
        printf("该文件夹下不存在%s",str);
        return 0;
    }


    while(1)
    {
        printf("是否确认?(Y/N)");
        cin>>c;
        if((c=='y'||c=='Y')||(c=='n'||c=='N'))
            break;

    }

    if(c=='n'||c=='N')
        return 0;

    blocknum=dir->list[i].fnum;

    flagdir=(struct DIR *)(file+blocknum*BLOCK_SIZE);

    while(m!=LIST_SIZE)
    {
        if(strcmp(flagdir->list[m].fname,"")!=0)
        {
            printf("该目录下有子文件或者子目录,不能删除该目录");
        }
        m++;
    }

    strcpy(dir->list[i].fname,"");		//父目录DIR
    strcpy(dir->list[i].exname,"");
    dir->list[i].fnum=0;


    strcpy(flagdir->list[0].fname,"");			//要删除目录的DIR
    strcpy(flagdir->list[0].exname,"");
    flagdir->list[0].fnum=0;

    strcpy(flagdir->list[1].fname,"");
    strcpy(flagdir->list[1].exname,"");
    flagdir->list[0].fnum=0;

    MAP->maplist[blocknum]=0;
    FAT->id[blocknum]=0;
    FAT->id[0]=FAT->id[0]+1;

    return 0;
}

/*
*更改当前目录(cd命令)
*/
int changedir(char *str)
{
    int i,j;
    int blocknum;			//当前目录位置
    int flagnum;			//temp的目录位置
    struct DIR * flagdir,*dir;
    struct fatid * FAT;
    string strflag;     //为了改当前显示的代码


    dir=(struct DIR *)(file+currentdir*BLOCK_SIZE);

    if(strcmp("..",str)==0)					//判断是不是上层目录
        {
        blocknum=currentdir;
        if(dir->list[0].fnum==dir->list[1].fnum)	//根目录的特征
            {
            return 1;
            }

        currentdir=dir->list[1].fnum;							//改变当前目录指针

        flagdir=(struct DIR *)(file+currentdir*BLOCK_SIZE);		//去上层的目录地址

        for(int j=0;j<LIST_SIZE;j++)
        {
            if(flagdir->list[j].fnum==blocknum)
            {
                strflag=flagdir->list[j].fname;
                break;

            }
        }
        CURRENT=CURRENT.substr(0,(CURRENT.length()-strflag.length())-1);
        return 1;
        }

    for(i=2;i<LIST_SIZE;i++)									//子目录
        {
        if(strcmp(dir->list[i].fname,str)==0&&strcmp(dir->list[i].exname,"dir")==0)
        {
            currentdir=dir->list[i].fnum;
            break;
        }
        }


    if(i>LIST_SIZE)
    {
        printf("找不到指定的目录%s\n",str);
        return 0;
    }

    CURRENT=CURRENT+str+"\\";
    return 1;
}

/*
*创建文件
*/
int create(char *str,int length)
{
    //getfilename
    int i,j,l,t,k;
    int blockdir;
    int fid;		//FAT的首块号
    int flag;		//文件的首块判断
    char name[8]={0};	//文件名称
    char exname[3]={0};	//文件扩展名
    int templength;      	//temp文件长度

    struct fatid * FAT;
    struct DIR *dir;
    struct map *MAP;

    dir=(struct DIR *)(file+(currentdir)*BLOCK_SIZE);
    MAP=(struct map *)(file+(FATNUM+1)*BLOCK_SIZE);
    FAT=(struct fatid *)(file+BLOCK_SIZE);
    templength=length;

    l=strlen(str);
    //取文件名
    for(i=0;i<l;i++)
    {

        name[i]=str[i];
        if(str[i+1]=='.')
            break;
    }

    if(i>=8)
    {
        printf("文件名称过长\n");
        return 0;
    }

    //去扩展名
    j=0;
    i++;
    i++;//除去点
    k=l-i;
    for(j=0;j<k;j++)
    {

        if(str[i]=='\0')
            break;
        exname[j]=str[i];
        i++;
    }
    if(strcmp(name,"0")==0)
    {
        printf("文件名称不能为空\n");
        return 0;
    }

    if(length>FAT->id[0])
    {
        printf("文件超出磁盘容纳空间\n");
        return 0;
    }


    for(i=2;i<LIST_SIZE;i++)
    {
        if(strcmp(dir->list[i].fname,name)==0&&strcmp(dir->list[i].exname,exname)==0)
        {
            printf("该文件夹下,已经有同名文件");
            return 0;
        }
        if(strcmp(dir->list[i].fname,"")==0)
        {
            break;
        }

    }
    if(i>LIST_SIZE)
    {
        printf("内存不足\n");
        return 0;
    }
    strcpy(dir->list[i].fname,name);
    strcpy(dir->list[i].exname,exname);
    dir->list[i].length=length;

    flag=1;
    j=DATABEG+1;

    while(1){//不断循环
        if(MAP->maplist[j]!=1)
        {
            if(!templength--)	//当length全部被分配完截止
                break;
            //上一块的地址
            if(flag)		//第一次分配是的首地址
                {
                dir->list[i].fnum=j;		//给文件的首块

                }
            MAP->maplist[j]=1;				//MAP减少
            if(!flag)
            {
                FAT->id[t]=j;
                FAT->id[0]=FAT->id[0]-1;
            }
            t=j;
            flag=0;
        }
        j++;
    }
    FAT->id[t]=-1;
    FAT->id[0]=FAT->id[0]-1;
    return 1;
}

/**
复制文件
*/
int cp(char *str,char *newname)
{
    int i,j,k,l,length;
    char name[8]={0};	//文件名称
    char exname[3]={0};	//文件扩展名
    struct DIR *dir;
    l=strlen(str);
    //取文件名
    for(i=0;i<l;i++)
    {
        name[i]=str[i];
        if(str[i+1]=='.')
            break;
    }
    //去扩展名
    j=0;
    i++;
    i++;//除去点
    k=l-i;
    for(j=0;j<k;j++)
    {

        if(str[i]=='\0')
            break;
        exname[j]=str[i];
        i++;
    }
    if(strcmp(newname,"")==0)
    {
        printf("文件名不能为空\n");
        return 0;
    }
    dir=(struct DIR *)(file+currentdir*BLOCK_SIZE);

    for(i=2;i<LIST_SIZE;i++)									//子文件
        {
        if(strcmp(dir->list[i].fname,name)==0&&strcmp(dir->list[i].exname,exname)==0)
            break;

        }
    if(i>LIST_SIZE)
    {
        printf("找不到指定的文件%s\n",str);
        return 0;
    }
    length=dir->list[i].length ;
    create(newname,length);
}

/*
*删除文件
*/
int delfile(char *str)
{
    int i,j,l,k;
    int blocknum;       //要删除的首块地址
    int temp;
    char name[8]={0};	//文件名称
    char exname[3]={0};	//文件扩展名
    char c='a';

    struct DIR *dir;
    struct fatid *FAT;
    struct map *MAP;

    l=strlen(str);
    //取文件名
    for(i=0;i<l;i++)
    {

        name[i]=str[i];
        if(str[i+1]=='.')
            break;
    }


    //去扩展名
    j=0;
    i++;
    i++;//除去点
    k=l-i;
    for(j=0;j<k;j++)
    {

        if(str[i]=='\0')
            break;
        exname[j]=str[i];
        i++;
    }


    if(strcmp(str,"")==0)
    {
        printf("文件名不能为空\n");
        return 0;
    }

    dir=(struct DIR *)(file+(currentdir)*BLOCK_SIZE);
    MAP=(struct map *)(file+(FATNUM+1)*BLOCK_SIZE);
    FAT=(struct fatid *)(file+BLOCK_SIZE);

    for(i=2;i<LIST_SIZE;i++)
    {
        if((strcmp(dir->list[i].fname,name)==0)&&(strcmp(dir->list[i].exname,exname)==0))
            break;

    }
    if(i>LIST_SIZE)
    {
        printf("找不到%s 文件\n",str);
        return 0;
    }

    if(c=='n'||c=='N')
        return 0;

    blocknum=dir->list[i].fnum;
    dir->list[i].fnum=0;				//把目录项还原
    strcpy(dir->list[i].exname,"");
    strcpy(dir->list[i].fname,"");
    dir->list[i].length=0;


    //处理FAT AND MAP 表

    while(FAT->id[blocknum]!=-1)
    {
        temp=FAT->id[blocknum];;
        FAT->id[blocknum]=0;
        FAT->id[0]=FAT->id[0]+1;
        MAP->maplist[blocknum]=0;
        blocknum=temp;
    }
    return 0;
}
/*
 *重命名文件(将当前文件复制给一个新文件,并删除当前文件)
 */

void rename(char *str,char *newname){
    cp(str,newname);
    delfile(str);
}

/**
退出系统
*/
int exit()
{
    fp=fopen(FilePath,"w+");
    fwrite(file,sizeof(char),DISK_SIZE,fp);
    fclose(fp);
    free(file);
    return 1;
}


void welcome()
{
    //欢迎列表

    printf("--------------------------------------------------\n");
    printf("\n以下是使用说明\n");
    printf("format          : 对磁盘格式化.\n");
    printf("exit            : 安全退出该文件系统,保存信息.\n");
    printf("mkdir  dirname  ; 创建子目录.\n");
    printf("rmdir  dirname  : 删除子目录.\n");
    printf("ls     dirname  : 显示当前目录下信息.\n");
    printf("cd     dirname  : 更改当前目录.\n");
    printf("create filename length : 创建一个新文件.\n");
    printf("rm     filename : 删除文件.\n");
    printf("cp oldname newname: 复制文件.\n");
    printf("rename oldname newname : 重命名文件.\n");
    printf("\n--------------------------------------------\n");

    //申请虚拟空间
    file=(char *)malloc(DISK_SIZE*sizeof(char));

    //加载
    if((fp=fopen(FilePath,"r"))!=NULL)
    {
        fread(file,sizeof(char),DISK_SIZE,fp);
        printf("加载磁盘文件%s文件成功,现在可以操作\n\n",FilePath);
    }else
    {
        printf("这是第一次使用文件管理系统");
    }


}

int main()
{
    int length;
    char newname[20];
    welcome();
    format();
    while(1)
    {
        cout<<CURRENT<<"#";
        cin>>cmd;
        if(strcmp(cmd,"format")==0){
            free(file);
            file=(char*)malloc(DISK_SIZE*sizeof(char));  //重新分配空间
            format();
        }else if(strcmp(cmd,"mkdir")==0)
        {
            scanf("%s",command);
            mkdir(command);
        }else if(strcmp(cmd,"rmdir")==0)
        {
            scanf("%s",command);
            rmdir(command);
        }
        else if(strcmp(cmd,"ls")==0)
        {
            listshow();
        }else if(strcmp(cmd,"cd")==0)
        {
            scanf("%s",command);
            changedir(command);
        }else if(strcmp(cmd,"create")==0)
        {
            cin>>command>>length;
            create(command,length);
        }else if(strcmp(cmd,"cp")==0)
        {
            cin>>command>>newname;
            cp(command,newname);
        }else if(strcmp(cmd,"rm")==0)
        {
            scanf("%s",command);
            delfile(command);
        }
        else if (strcmp(cmd,"rename")==0){
            cin>>command>>newname;
            rename(command,newname);
        }
        else if(strcmp(cmd,"exit")==0){
            exit();
            break;
        }
        else {
            printf("无效指令,请重新输入:\n");
        }
    }
    printf("Thank you for using my file system!\n");
    return 0;
}
  系统运维 最新文章
配置小型公司网络WLAN基本业务(AC通过三层
如何在交付运维过程中建立风险底线意识,提
快速传输大文件,怎么通过网络传大文件给对
从游戏服务端角度分析移动同步(状态同步)
MySQL使用MyCat实现分库分表
如何用DWDM射频光纤技术实现200公里外的站点
国内顺畅下载k8s.gcr.io的镜像
自动化测试appium
ctfshow ssrf
Linux操作系统学习之实用指令(Centos7/8均
上一篇文章      下一篇文章      查看所有文章
加:2022-06-14 22:57:06  更:2022-06-14 22:58:37 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/18 22:06:00-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码