【操作系统】磁盘文件管理系统

实验六  磁盘文件管理的模拟实现

  •  实验目的

文件系统是操作系统中用来存储和管理信息的机构,具有按名存取的功能,不仅能方便用户对信息的使用,也有效提高了信息的安全性。本实验模拟文件系统的目录结构,并在此基础上实现文件的各种操作方法。

通过本实验,深入理解文件和目录的作用和功能,熟悉与文件有关的系统调用,从而更好地掌握文件系统功能。

  •  实验内容

编程模拟实现磁盘文件管理。采用单级目录结构,存放用户的所有文件,系统提供创建文件、打开文件、读文件、写文件、关闭文件、删除文件命令。

(1)文件存储空间的分配采用位示图进行管理,该部分内容请参考实验5。磁盘信息如下:

现有一个磁盘组,共有8个柱面。每个柱面有4个磁道,每个磁道又划分成4个物理盘块,假设1个磁盘块大小为128B。磁盘的空间使用情况用位示图表示。位示图用若干个字构成,每一位对应一个磁盘块。“1”表示占用,“0”表示空闲。假定字长为16位,一个字可用来模拟磁盘的一个柱面。位示图的初始状态为第1个字为“1”,其他全部空闲。

(2)文件目录采用单级目录结构。整个文件系统中只建立一张文件目录表UFD,每个文件占一个目录项,目录项中含文件名、文件保护方式、文件长度等属性。

文件名

文件保护方式

文件当前长度

文件最大长度

文件所在地址

图1 用户文件目录表UFD

文件所在地址存放文件分配的磁盘块号。

文件保护方式:1表示文件可读,2表示文件可写,3表示文件可读写执行。

(3)系统建立一张用户打开文件表(UOF,用以记录系统当前正在使用的文件。假定最多允许打开4个文件,该表应设置4项。当打开文件个数超过4个时,应给出错误信息。用户打开文件表(UOF)的结构如下图所示。

图2 用户打开文件表(UOF)

图2中:

“文件操作方式”是指文件打开后要执行的操作

“状态”指用户打开文件表的各个表项为空表目或被占用。

读写指针用来指出对文件的存取位置。初始状态下,读指针=1,写指针=文件长度(追加写)。

(4)该文件系统提供6条命令:创建、打开、读、写、关闭、删除。各命令说明如下。

  • 创建一个文件,当用户要在磁盘上建立一个文件时,首先使用create命令向系统提出创建文件的请求:

fd= create(文件名,文件最大字节长度,文件保护方式);

例如:

fd= create(myfile1,200,2);

由文件最大长度计算出文件应占用的磁盘块数,然后为文件分配空间,并登记在用户文件目录表UFD中,同时登记在UOF表中。

不成功,返回-1; 成功返回文件描述符,即在UOF表中的序号。

  • 写文件命令 (文件描述符或文件名)

write(文件描述符或文件名,要写的字节个数);

例如:

write(myfile1,100);    模拟100个字节信息写入文件中。

不成功,返回-1,成功返回写入的字节个数

  • 打开文件命令

fd= open(文件描述符或文件名,操作方式); 

例如:fd=open(a.txt);

不成功,返回-1; 成功返回文件描述符,即在UOF表中的序号。

  • 读文件命令(选做)

read(文件描述符或文件名,要读的字节个数);

不成功,返回-1; 成功返回读取的字节个数

  • 关闭文件命令

close(文件描述符或文件名);

不成功,返回-1; 成功返回0

  • 删除文件命令

delete(文件名);

不成功,返回-1; 成功返回0

三. 测试用例

1】创建文件,记录各个数据结构情况

以下将创建6个文件,且包含3种文件保护方式,文件大小不完全相同。

(1)创建文件f1,文件大小 = 5,文件保护方式 = 3。

(2)创建文件f2,文件大小 = 5,文件保护方式 = 3。

(3)创建文件f3,文件大小 = 10,文件保护方式 = 3。

(4)创建文件f4,文件大小 = 5,文件保护方式 = 1。

(5)创建文件f5,文件大小 = 5,文件保护方式 = 3。

(6)创建文件f6,文件大小 = 5,文件保护方式 = 2。

上述文件创建完毕后,磁盘位示图和文件列表的情况如下图所示。

UOF为空状态,显示情况如下图所示。

2】读写文件,记录各个数据结构情况

在此步骤中,应该先打开文件,再对文件进行读/写操作,最后关闭文件。如果直接读/写文件,程序会提示相应报错。打开文件的操作序列如下所示。

(1)打开文件f1,文件操作方式 = 3。

(2)打开文件f2,文件操作方式 = 3。

(3)打开文件f3,文件操作方式 = 3。

(4)打开文件f4,文件操作方式 = 1。

(5)打开文件f5,文件操作方式 = 3。

由(5)可知,当打开文件数量大于4时,程序会提示打开文件数目超过上限,因此符合本实验中的【假定最多允许打开4个文件,该表应设置4项。当打开文件个数超过4个时,应给出错误信息】的要求。

此时UOF的情况如下图所示。

(6)读取文件f1,读取字节数 = 3。

此时UOF的情况如下图所示。可以发现f1文件的读指针有所修改。

(7)读取文件f2,读取字节数 = 10。

 由(7)可知,当从当前文件读指针开始,经过输入的读取字节数后,如果超过了文件的当前长度,程序会提示读取文件长度超过上限。

(8)写入文件f3,写入字节数 = 10。

此时UOF的情况如下图所示。可以发现f3文件的写指针、文件当前大小有所修改。

此时磁盘位示图的情况如下图所示。

(9)写入文件f4,写入字节数 = 5。

 由(9)可知,如果当前文件的保护方式与操作方式存在不兼容的情况,程序会提示该文件不能操作写。

(10)关闭文件f4。

(11)关闭文件f3。

此时UOF的情况如下图所示。可以发现f3文件和f4文件的信息已经不存在于UOF中,说明关闭操作成功。

此时磁盘位示图的情况如下图所示。可以发现文件依然存在于磁盘中,因此关闭操作并不会导致文件被删除的情况发生。

(12)关闭f2文件。

此时UOF的情况如下图所示。可以发现f2文件的信息已经不存在于UOF中,说明关闭操作成功。

(13)关闭f1文件。

此时UOF的情况如下图所示。可以发现f1文件的信息已经不存在于UOF中,说明关闭操作成功。

当前UOF为空,说明没有文件处于打开状态。

3】删除文件,记录各个数据结构情况

(1)删除f2文件。

此时磁盘位示图的情况如下图所示。可以发现f2文件的信息已经不存在于磁盘位示图中,说明删除操作成功。

(2)删除f3文件。

此时磁盘位示图的情况如下图所示。可以发现f3文件的信息已经不存在于磁盘位示图中,说明删除操作成功。

(3)删除f4文件。

此时磁盘位示图的情况如下图所示。可以发现f4文件的信息已经不存在于磁盘位示图中,说明删除操作成功。

后面将随机删除磁盘中剩余的各个文件,此处不再进行赘述。

4】所有的文件都删除掉时,磁盘恢复为初始化状态

四. 实验分析和总结

1】数据结构说明

(1)FCB的数据结构

FCB的代码实现如下图所示。

在本实验中,利用struct构造FileInfo结构体,实现对文件基本信息的记录,即文件控制块。

该数据结构的基本变量包括:文件名字的字符串file_name、文件大小的整型单变量file_size、文件分配扇区的一维数组allocated_sectors、文件保护方式的整型单变量protection。

(2)UOF的数据结构

UOF的代码实现如下图所示。

在本实验中,利用struct构造UOF结构体,实现对处于打开状态的各个文件进行记录,即用户文件打开表。

该数据结构的基本变量包括:文件名字的字符串file_name、文件操作方式的整型单变量protection、文件当前大小的整型单变量file_size、文件读指针的整型单变量read、文件写指针的整型单变量write、文件状态的整型单变量state(在本次实验中并没有实际用到)。

(3)磁盘空间的数据结构

磁盘空间的代码实现如下图所示。

在本实验中,利用struct构造StorageManager结构体,实现磁盘空间的初始化和管理,以及链接相应的文件信息。

该数据结构的基本变量包括:可用扇区总数的整型单变量available_sectors、磁盘位示图的二维数组bitmap、文件映射的哈希表files、打开文件映射的哈希表user。

该数据结构的功能包括:构造磁盘空间函数createFile、创建文件函数createFile、显示磁盘存储状态函数displayStatus、显示磁盘中的文件序列函数fileDetails、删除文件函数deleteFile、打开文件函数openFile、关闭文件函数closeFile、写入文件函数writeFile、读取文件函数readFile、显示UOF状态函数displayUOF。

2】程序流程图

1)主函数的程序流程图

2)构造磁盘空间函数的程序流程图

3)创建文件函数的程序流程图

4)显示磁盘存储状态函数的程序流程图

(5)显示磁盘中的文件序列函数的程序流程图

6)删除文件函数的程序流程图

7)打开文件函数的程序流程图(第一、二个判断框右侧为否,下测为是,画错)

8)关闭文件函数的程序流程图

9)写入文件函数的程序流程图

10)读取文件函数的程序流程图

11)显示UOF函数的程序流程图

3】程序运行结果,打印程序运行时的初值和运行结果

程序在测试用例下的运行结果如【三、测试用例】处所示。测试用例的流程图如下图所示。

4】实验知识点总结,实验收获与体会

1:单级文件目录是最简单的文件目录,只适用于单用户环境。在单级目录中,利用用户提供的文件名,用顺序查找法直接从文件目录中找到指名文件的目录项。
       其优点是:简单易实现,实现了“按名存取”。
       其缺点是:(1)查找速度慢。在目录文件中查找文件目录项需要时间长。②不允许重名。同一个目录中的文件不允许同名。③不便于实现文件共享。

2:两级目录结构由【主文件目录MFD】和【用户子目录UFD】组成。
       其优点是:①文件重名问题。每个用户可以使用相同的文件名。②提高了检索目录的速度。查找时间只是该用户所拥有的文件数目的一半时间,而不是所有文件的一半时间。③文件共享:允许不同用户使用不同文件名来访问同一个文件。原则上只要把对应的目录项指向同一物理位置的文件即可。
       其缺点是:用户不能对自己的文件进行分类管理。
       查找文件的逻辑结构如下图所示。

3:访问一个文件过程:根据文件名对目录进行查询,找出该文件的FCB或索引结点;

根据FCB中的盘块号,换算出物理地址,最后,把文件读进来。

4:在文件保护方式中,一共有3种状态。其中,1表示文件可读,2表示文件可写,3表示文件可读写执行。

5:在本次实验中,深入了解了文件系统的工作原理和如何模拟文件的创建、写入、打开、读取、关闭和删除等操作。同时,遇到了许多可能导致操作失败的情况,如磁盘空间不足、文件不存在、文件打开数超限等,因此学会了如何在程序中进行错误处理和返回适当的错误代码。

6:实验要求模拟文件系统,因此更加了解了系统调用的重要性。系统调用是用户程序与操作系统之间的桥梁,它允许用户程序与系统资源进行交互。同时,通过模拟用户打开文件表,学会了如何在系统中管理多个同时打开的文件,深入理解了多任务操作系统中的文件管理。

5】实验源代码

#include <iostream>

#include <vector>

#include <unordered_map>

using namespace std;

const int MAXOPEN = 4;

const int MAXBYTE = 50;

// FCB or one-UFD

struct FileInfo {  

    string file_name;               // 文件名字

    int file_size;                  // 文件大小

    vector<int> allocated_sectors;  // 文件分配的扇区

    int protection;                 // 文件保护方式

};

// UOF

struct UOF {

    string file_name;   //文件名字

    int protection;     //文件操作方式

    int file_size;      //文件大小 (当前)

    int read;           //文件读指针

    int write;          //文件写指针

    int state;          //文件状态

    //int file_path;        //文件地址 ,不如直接看磁盘。

};

// Disk

struct StorageManager {                    

    int available_sectors;                  // 可用扇区总数

    vector<vector<int>> bitmap;             // 磁盘位图

    unordered_map<string, FileInfo> files;  // 文件映射

    unordered_map<string, UOF> user;        // 打开文件映射

    StorageManager();                       // 构造函数yes

    bool createFile(const string&, int, int);   // 创建文件yes

    void displayStatus();                   // 显示存储状态yes

    void fileDetails(const FileInfo&);      // 显示文件详情yes

    bool deleteFile(const string&);         // 删除文件yes

   

    bool openFile(const string&, int);      // 打开文件,文件名+操作方式yes

    bool closeFile(const string&);          // 关闭文件,文件名yes

    bool writeFile(const string&, int);     // 写入文件,文件名+写入字节数yes

    bool readFile(const string&, int);      // 读取文件,文件名+读取字节数 yes

    void displayUOF();                      // 显示UOF

};

// show UOF

void StorageManager::displayUOF(){

    cout<<"文件打开表UOF:"<<endl;

    for(const auto& pair:user){

        cout<<pair.first<<"文件:";

        cout<<"[文件操作方式]"<<pair.second.protection<<"\t";

        cout<<"[文件当前大小]"<<pair.second.file_size<<"\t";

        cout<<"[文件读指针]"<<pair.second.read<<"\t";

        cout<<"[文件写指针]"<<pair.second.write<<"\t";

        cout<<"[文件状态]"<<pair.second.state;

        cout<<endl;

    }

}

// 读取文件

bool StorageManager::readFile(const string& name, int byte){

    auto it = user.find(name);

    if(it == user.end()){

        cout<<"读取文件错误:UOF里没有这个文件。"<<endl;

        return false;

    }

   

    UOF temp = it->second;

    if(temp.protection != 3 and temp.protection != 1){

        cout<<"读取文件错误:该文件不能操作读。"<<endl;

        return false;

    }

   

    if(temp.read + byte > temp.file_size){

        cout<<"读取文件错误:读取文件长度超过上限。"<<endl;

        return false;

    }

   

    // allow reading

    it->second.read += byte;

   

    return true;

}

// 写入文件

bool StorageManager::writeFile(const string& name, int byte){

    auto it = user.find(name);

    if(it == user.end()){

        cout<<"写入文件错误:UOF里没有这个文件。"<<endl;

        return false;

    }

   

    UOF temp = it->second;

    if(temp.protection != 3 and temp.protection != 2){

        cout<<"写入文件错误:该文件不能操作写。"<<endl;

        return false;

    }

   

    if(temp.write + byte > MAXBYTE){

        cout<<"写入文件错误:写入文件长度超过上限。"<<endl;

        return false;

    }

   

    // check disk

    if(available_sectors < byte){

        cout<<"写入文件错误:磁盘空间不足。"<<endl;

        return false;

    }

   

    auto find = files.find(name);

    FileInfo add = find->second;

   

    int addbyte = byte;

    // modify bitmap

    for(int i=0;i<bitmap.size()&&addbyte>0;++i){

        for(int j=0;j<bitmap[i].size()&&addbyte>0;++j){

            if(bitmap[i][j]==0){

                bitmap[i][j]=1;

                find->second.allocated_sectors.push_back(i*16+j);   //allocated_sectors

                --addbyte;

                --available_sectors;

            }

        }

    }

   

    // allow writing

    it->second.write += byte;       // 修改写指针

    it->second.file_size += byte;   // 修改当前文件长度

   

    // update FCB

    find->second.file_size += byte;

    fileDetails(find->second);

   

    return true;

}

// 关闭文件函数

bool StorageManager::closeFile(const string& name){

    auto it = user.find(name);

    if(it == user.end()){

        cout<<"关闭文件错误:UOF里没有这个文件。"<<endl;

        return false;

    }

   

    user.erase(it);

   

    return true;

}

// 打开文件函数

bool StorageManager::openFile(const string& name, int opt){

    auto it = files.find(name);

    if(it == files.end()){

        cout<<"打开文件错误:没有这个文件。"<<endl;

        return false;

    }

   

    FileInfo temp = it->second;

   

    if(temp.protection == 1){

        if(opt != 1){

            cout<<"打开文件错误:文件保护方式有限制。"<<endl;

            return false;

        }

    }

    else if(temp.protection == 2){

        if(opt != 2){

            cout<<"打开文件错误:文件保护方式有限制。"<<endl;

            return false;

        }

    }

   

    auto newit = user.find(name);

    if(newit != user.end()){

        cout<<"打开文件错误:这个文件已经打开。"<<endl;

        return false;

    }

   

    if(user.size() >= MAXOPEN){

        cout<<"打开文件错误:打开文件数目超过上限。"<<endl;

        return false;

    }

   

    // 文件名字、操作、当前大小、读ptr、写ptr、状态

    UOF t{name, opt, temp.file_size, 1, temp.file_size, 0};

    user[name] = t;     //hash setting

   

    return true;

}

// 构造函数  8个柱面。每个柱面有4个磁道,每个磁道又划分成4个物理盘块。

StorageManager::StorageManager() : available_sectors(128) {

    bitmap.resize(8, vector<int>(16, 0));   // 构造8*16个空盘块

    for (int j = 0; j < 16; ++j) {

        bitmap[0][j] = 1;  // 预留第一行作为系统文件,该柱面不可用

    }

}

// 创建文件函数

bool StorageManager::createFile(const string& name, int size, int protection) {

    if (files.find(name) != files.end()) {  // 如果文件名字不在末尾,则冲突

        cout << "创建文件错误: 文件已存在。"<< endl;

        return false;

    }  

    if (size > available_sectors) {     // 如果文件大小大于空闲扇区大小

        cout << "创建文件错误: 磁盘空间不足。"<< endl;

        return false;

    }

   

    // 创建新文件的FCB

    FileInfo newFile{ name, size, {} , protection};

   

    // 更新位示图中信息

    for (int i = 0; i < bitmap.size() && size > 0; ++i) {

        for (int j = 0; j < bitmap[i].size() && size > 0; ++j) {

            if (bitmap[i][j] == 0) {    // 如果这个盘块为空

                bitmap[i][j] = 1;   // 设置为已经分配

                newFile.allocated_sectors.push_back(i * 16 + j);    // 分配区增加这个盘块

                --size;     // 空闲区大小-=1

                --available_sectors;    // 同上

            }

        }

    }

    files[name] = newFile;  // hash表设置

    fileDetails(newFile);   // 显示新建文件详情

    return true;

}

// 显示磁盘分配情况函数

void StorageManager::displayStatus() {

    cout << "磁盘位图:" << endl;

    for (int i = 0; i < bitmap.size(); ++i) {

        for (int j = 0; j < bitmap[i].size(); ++j) {

            cout << bitmap[i][j] << ' ';

        }

        cout << endl;   // 换行显示

    }

   

    cout << endl << "文件列表:" << endl;

    for (const auto& pair : files) {

        cout <<"文件'"<< pair.first << "'的大小: " << pair.second.file_size << endl;

        fileDetails(pair.second);

    }

    cout << endl;

}

// 显示文件内存详情函数

void StorageManager::fileDetails(const FileInfo& file) {

    cout << "文件 '" << file.file_name << "' 的详细信息:"<< endl;

    for (int sector : file.allocated_sectors) {

        cout << "扇区: " << sector << ";";    //遍历扇区

    }

    cout << endl;

}

// 删除文件函数

bool StorageManager::deleteFile(const string& name) {

    auto it = files.find(name);

    if (it == files.end()) {

        cout << "删除文件错误: 文件不存在。"<< endl;

        return false;

    }

    for (int sector : it->second.allocated_sectors) {

        int i = sector / 16;

        int j = sector % 16;

        bitmap[i][j] = 0;

        ++available_sectors;

    }

    files.erase(it);

    auto another = user.find(name);

    if (another != user.end()){

        user.erase(another);

    }

   

    cout << "文件 '" << name << "' 已删除。"<< endl;

    return true;

}

// 菜单函数

void menu(StorageManager manager){

    cout << "根据数字提示选择操作: " << endl;

    cout << "0:退出系统,1:创建文件, 2:删除文件" << endl;

    cout << "4:打开文件,5:读取文件, 6:写入文件, 7:关闭文件" << endl;

    cout << "3:磁盘位示图,8:用户文件打开表"<<endl;

}

// 主函数

int main() {

    StorageManager manager;

    int action;

    string filename;

    int filesize;

    int protection;

    int byte;

    while (true) {

        bool flag = 1;

        cout << endl;

        menu(manager);

        cin >> action;

        cout << endl;

        switch (action) {

            // 1,创建文件

            case 1:

                cout << "输入文件名: ";

                cin >> filename;

                while (1){

                    cout << "输入文件大小: ";

                    cin >> filesize;

                    if(filesize<=0){

                        cout<<"文件大小必须为正,请重新输入!"<<endl;

                    }

                    else{

                        break;

                    }

                }

                while (1) {

                    cout << "输入文件保护方式:";

                    cin >> protection;

                    if(protection == 1 or protection == 2 or protection == 3){

                        break;

                    }

                    else{

                        cout<<"文件保护方式输入错误,请重新输入!"<<endl;

                    }

                }

                if (manager.createFile(filename, filesize, protection)) {

                    cout << "文件创建成功。"<<endl;

                }

                break;

            //2,删除文件

            case 2:

                cout << "输入要删除的文件名: ";

                cin >> filename;

                if (manager.deleteFile(filename)) {

                    cout << "文件删除成功。"<<endl;

                }

                break;

            //3,磁盘位示图

            case 3:

                manager.displayStatus();

                break;

            //4:打开文件

            case 4:

                cout << "输入要打开的文件名: ";

                cin >> filename;

                while(1){

                    cout<<"请输入文件操作方式:";

                    cin >> protection;

                    if(protection != 1 and protection != 2 and protection != 3){

                        cout<<"文件操作方式错误,请输入1、2、3中的其中一个。"<<endl;

                    }

                    else {

                        break;

                    }

                }

                if (manager.openFile(filename,protection)) {

                    cout << "文件打开成功。"<<endl;

                }

                break;

            //5:读取文件

            case 5:

                cout<<"输入要读取的文件名:";

                cin>>filename;

                while(1){

                    cout<<"输入要读取的字节数:";

                    cin>>byte;

                    if(byte <= 0){

                        cout<<"读取字节大小必须为正,请重新输入!"<<endl;

                    }

                    else{

                        break;

                    }

                }

                if(manager.readFile(filename, byte)){

                    cout<<"文件读取成功。"<<endl;

                }

                break;

            //6:写入文件

            case 6:

                cout<<"输入要写入的文件名:";

                cin>>filename;

                while(1){

                    cout<<"输入要写入的字节数:";

                    cin>>byte;

                    if(byte <= 0){

                        cout<<"写入字节大小必须为正,请重新输入!"<<endl;

                    }

                    else{

                        break;

                    }

                }

                if(manager.writeFile(filename, byte)){

                    cout<<"文件写入成功。"<<endl;

                }

                break;

            //7:关闭文件

            case 7:

                cout << "输入要关闭的文件名: ";

                cin >> filename;

                if(manager.closeFile(filename)){

                    cout << "文件关闭成功。"<<endl;

                }

                break;

            //8:UOF

            case 8:

                manager.displayUOF();

                break;

            case 0:

                cout << "程序退出,感谢使用。"<<endl;

                flag = 0;

                break;

            default:

                cout << "无效的数字操作,请重新输入。"<<endl;

                break;

        }

       

        if(!flag){

            break;

        }

    }

   

    return 0;

}

五.实验指导

1.  主要的数据结构(供参考)

UFD、UOF表可采用结构数组,也可采用链表方式,下面是结构数组方式的定义。

#define OPEN_FILE_MAX    4

#define FILE_NAME_MAX    20 

#define FILE_MAX      10   //系统中可创建的文件数量最大值

#define FILE_BLOCK_MAX      10   //文件磁盘块最大值

struct  FCB{

    // 文件控制块

    int    file_descriptor;            // 文件标识符

    char   file_name[FILE_NAME_MAX];  // 文件名

    int    protected_mode;             // 1:可读;2:可写;3:可读写执行

    int    file_current_length;          // 文件当前长度(字节)

    int    file_max_length;            // 文件最大长度(字节)

    // 以下是文件存储空间分配时产生的值,不需要用户定义

    int    length;                     // 文件的块数

    int    block[FILE_BLOCK_MAX];   // 存放文件的具体盘块号

    …….

}  UFD_table[FILE_MAX];  // UFD表信息,文件目录结构

struct  UOF{

    char file_name[FILE_NAME_MAX];

    int operate_mode;   // 打开后要执行的操作    1只读 2读写 3读写执行

    int read_pointer;   // 初始状态下为1

    int write_pointer;  // 初始状态下为文件长度

    int file_current_length;

    int file_path;

    int state;

} UOF_table[OPEN_FILE_MAX];       // 用户打开文件表

2. 文件系统执行流程

实验中,应先建立用户文件目录和用户打开文件表,然后给出一个菜单,请求用户选择要执行的操作。

(1)文件系统执行流程如下图所示。

2创建文件命令和流程图

fd= create(文件名,文件最大字节长度,文件保护方式)

3)写文件命令及其流程图

write(文件描述符或文件名,要写的字节个数);

4)打开文件命令及其流程图

fd= open(文件描述符或文件名,操作方式);

5读文件命令及其流程图

read(文件描述符或文件名,要读的字节个数);

6)关闭文件命令及其流程图

close(文件描述符或文件名);

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【前端素材】推荐优质后台管理系统Spica Admin平台模板(附源码)

一、需求分析 后台管理系统是一种用于管理网站、应用程序或系统的工具&#xff0c;它通常作为一个独立的后台界面存在&#xff0c;供管理员或特定用户使用。下面详细分析后台管理系统的定义和功能&#xff1a; 1. 定义 后台管理系统是一个用于管理和控制网站、应用程序或系统…

会话技术之cookie和session

COOKIE 什么是COOKIE? Cookie是由网站存储在用户计算机上的小型文本文件&#xff0c;用于在用户访问网站时跟踪和识别用户。Cookie可以在用户的计算机上存储有关用户行为和偏好的信息&#xff0c;以便在用户下次访问相同网站时提供个性化的体验。以下是一些关于Cookie的重要…

C语言——指针——第2篇——(第20篇)

坚持就是胜利 文章目录 一、指针和数组二、二级指针1、什么是 二级指针&#xff1f;2、二级指针 解引用 三、指针数组模拟二维数组 一、指针和数组 问&#xff08;1&#xff09;&#xff1a;指针和数组之间是什么关系呢&#xff1f; 答&#xff1a;指针变量就是指针变量&…

【Linux】一站式教会:Ubuntu(无UI界面)使用apache-jmeter进行压测

&#x1f3e1;浩泽学编程&#xff1a;个人主页 &#x1f525; 推荐专栏&#xff1a;《深入浅出SpringBoot》《java对AI的调用开发》 《RabbitMQ》《Spring》《SpringMVC》 &#x1f6f8;学无止境&#xff0c;不骄不躁&#xff0c;知行合一 文章目录 前言一、Java…

C++:string类

标准库中的string类 string类 1. 字符串是表示字符序列的类 2. 标准的字符串类提供了对此类对象的支持&#xff0c;其接口类似于标准字符容器的接口&#xff0c;但添加了专门用于操作单字节字符字符串的设计特性。 3. string类是使用char(即作为它的字符类型&#xff0c;使用…

统计图曲线图绘制方法

统计图曲线图绘制方法 常用的统计图有条形图、柱形图、折线图、曲线图、饼图、环形图、扇形图。 前几类图比较容易绘制&#xff0c;饼图环形图绘制较难。 曲线图的曲线绘制较难&#xff0c;今提供曲线图的绘制方法供参考。 本方法采用C语言的最基本功能&#xff1a; &#xff…

【C++】——模板初阶 | STL简介

前言: 模板初阶 | STL简介 文章目录 一、模板初阶1.1 函数模板1.2 类模板 二、STL简介 &#xff08;了解&#xff09; 一、模板初阶 泛式编程&#xff08;Generic Programming&#xff09;指的是一种编程范式&#xff0c;其核心思想是编写可以在不同数据类型上通用的代码&#…

Linux系列讲解 —— 【Vim编辑器】在Ubuntu18.04中安装新版Vim

平时用的电脑系统是Ubuntu18.04&#xff0c;使用apt安装VIM的默认版本是8.0。如果想要安装新版的Vim编辑器&#xff0c;只能下载Vim源码后进行编译安装。 目录 1. 下载Vim源码2. 编译3. 安装4. 遇到的问题4.1 打开vim后&#xff0c;文本开头有乱码现象。4.2 在Vim编辑器中&…

通信入门系列——锁相环、平方环、Costas环

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

精酿啤酒:麦芽与啤酒花搭配的奥秘

麦芽和啤酒花是啤酒酿造过程中不可或缺的原料&#xff0c;它们的风味和特点对啤酒的口感和品质产生着深远的影响。Fendi Club啤酒在麦芽与啤酒花的搭配方面有着与众不同的技巧和见解&#xff0c;让啤酒的口感更加丰富和迷人。 首先&#xff0c;麦芽的选择是啤酒酿造的关键之一。…

C语言特殊函数

静态函数 背景知识&#xff1a;普通函数都是跨文件可见的&#xff0c;即在文件 a.c 中定义的函数可以在 b.c 中使用。 静态函数&#xff1a;只能在定义的文件内可见的函数&#xff0c;称为静态函数。 语法 staitc void f(void) // 在函数头前面增加关键字 static &#xff…

2024.2.22 C++QT 作业

思维导图 练习题 1>完善对话框&#xff0c;点击登录对话框&#xff0c;如果账号和密码匹配&#xff0c;则弹出信息对话框&#xff0c;给出提示”登录成功“&#xff0c;提供一个Ok按钮&#xff0c;用户点击Ok后&#xff0c;关闭登录界面&#xff0c;跳转到其他界面。如果账…

2024年开发者的最好选择!!没有之一

中国银河证券1月23日明确指出&#xff1a;鸿蒙应用将在2024年迎来爆发。 2024年Q2推出开发者Beta版&#xff0c;2024年Q4推出商用版。今年年终将有 5000 款应用完成原生鸿蒙开发&#xff0c;未来支持 50 万款应用。覆盖便捷生活、出行文旅、金融便利、社交资讯、生产力工具、影…

Stable Diffusion 3 Early Preview发布

2月22日&#xff0c;Stability AI 发布了 Stable Diffusion 3 early preview&#xff0c;这是一种开放权重的下一代图像合成模型。据报道&#xff0c;它继承了其前身&#xff0c;生成了详细的多主题图像&#xff0c;并提高了文本生成的质量和准确性。这一简短的公告并未附带公开…

节假日效应prophet预测模型和节假日识别错误

节假日效应是指在特定的节假日或纪念日期间&#xff0c;人们的行为和活动发生变化&#xff0c;从而影响到相应的时间序列数据&#xff08;股票或者其他&#xff09;。这种效应可能在多个领域产生影响&#xff0c;包括销售、交通、能源消耗等。 完整代码和数据可关注gzh’financ…

[算法沉淀记录] 排序算法 —— 归并排序

排序算法 —— 归并排序 算法介绍 归并排序是一种分治算法&#xff0c;由约翰冯诺伊曼在1945年发明。它的工作原理是将未排序的列表划分为n个子列表&#xff0c;每个子列表包含一个元素(包含一个元素的列表被认为是有序的)&#xff0c;然后重复合并子列表以生成新的有序子列表…

最简单方式把jar打包成Windows服务

废话 &#x1f622; 将JAR文件转化为Windows服务是一种高效且常见的Java应用部署策略。这种转变赋予了Java应用程序在Windows操作系统上以无界面后台服务模式运行的能力&#xff0c;从而实现了持续、稳定且可靠的功能提供。这种部署方式不仅提升了应用的可用性&#xff0c…

TreeData 数据查找

TreeData 数据查找 最近做需求的时候遇到了这样的一个需求&#xff0c;Tree组件数据支持查找&#xff0c;而且TreeData的数据层级是无限级的 开始想的事借助UI组件库&#xff08;Ant-design-vue&#xff09;中的Tree组件的相关方法直接实现,看了下api 发现没法实现&#xff0c;…

Java SpringBoot测试OceanBase

对上篇mysql导入到OceanBase中的数据库进行代码测试&#xff0c;写了个demo包含测试方法&#xff0c;在原mysql库中成功执行&#xff0c;迁移到OceanBase时看是否能不修改业务代码而成功执行测试方法&#xff1a; 代码基于SpringBoot MyBastis测试增删改查、批量新增、多表联…

onnx 1.16 doc学习笔记一:ONNX概念

onnx作为一个通用格式&#xff0c;很少有中文教程&#xff0c;因此开一篇文章对onnx 1.16文档进行翻译与进一步解释&#xff0c; onnx 1.16官方文档&#xff1a;https://onnx.ai/onnx/intro/index.html](https://onnx.ai/onnx/intro/index.html)&#xff0c; 如果觉得有收获&am…