你真的会用read()读【普通文件】吗?

原型如下:

#include <unistd.h>

ssize_t read (int __fd, void *__buf, size_t __nbytes);    

如果是读【普通文件】,可能的返回是:

  • 0读到了文件尾。
  • <= nbytes,可能是文件没有这么多字节了。
  • -1,出错。

注意,-1出错的时候,errno会返回错误码。

其中有一个errno需要引起我们注意,就是EINTR。手册里面是这么解释的:当任何数据没有读到的时候,如果调用被中断,返回-1且errno设置为EINTR。言外之意是如果读到了,会返回读了多少,这种有数据的不会返回-1。

看起来这个异常情况需要处理,避免真的不凑巧刚调用,被信号中断了,那其不是被误认为出错了吗?可是真的是这种情况要处理吗?

还真有人说需要处理(见https://blog.csdn.net/feit2417/article/details/82498653),他文章里面是这么说的:


分享一个工业级代码,read读文件数据。

读的过程中,调用被信号中断,于是返回一个EINTR错误,read读取失败。

由于没有读到数据而被意外中断,所以需要从新读数据。while (ret < 0 && EINTR == errno);

实例代码:

bzero(buf, sizeof
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,下面是一个简单的二级文件系统的设计实现,供参考: 1. 设计思路 二级文件系统是指在磁盘上,有一个主目录,每个子目录下可以有多个文件和子目录。该文件系统需要实现以下功能: - 创建目录 - 删除目录 - 进入子目录 - 退出子目录 - 创建文件 - 删除文件 - 打开文件 - 关闭文件 - 文件 - 写文件 为了实现这些功能,我们需要设计一些数据结构和函数来管理文件系统。 2. 数据结构设计 首先,我们需要设计一个用于存储文件信息的数据结构,包含文件名、文件大小、文件类型等信息。这里我们可以使用结构体来表示一个文件,如下所示: ```c struct file { char name[20]; // 文件名 int size; // 文件大小 int type; // 文件类型(0表示文件夹,1表示普通文件) char* content; // 文件内容(仅限普通文件) }; ``` 接下来,我们需要设计一个用于存储目录信息的数据结构,包含目录名、子目录列表、文件列表等信息。这里我们可以使用结构体来表示一个目录,如下所示: ```c struct directory { char name[20]; // 目录名 struct directory* parent; // 父目录指针 struct directory* subdirs; // 子目录列表 struct file* files; // 文件列表 }; ``` 其中,`parent`表示父目录指针,`subdirs`表示子目录列表,`files`表示文件列表。 3. 函数设计 接下来,我们需要设计一些函数来实现二级文件系统的各种功能。 首先,我们需要实现一个函数来初始化文件系统。该函数创建一个根目录,并返回根目录指针,如下所示: ```c struct directory* init_fs(); ``` 接下来,我们需要实现一个函数来创建目录。该函数在指定的父目录下创建一个子目录,并返回子目录指针,如下所示: ```c struct directory* create_directory(struct directory* parent, const char* name); ``` 接下来,我们需要实现一个函数来删除目录。该函数删除指定的目录及其下面的所有文件和子目录,如下所示: ```c void delete_directory(struct directory* dir); ``` 接下来,我们需要实现一个函数来进入子目录。该函数返回指定子目录的指针,如下所示: ```c struct directory* enter_directory(struct directory* parent, const char* name); ``` 接下来,我们需要实现一个函数来退出子目录。该函数返回父目录的指针,如下所示: ```c struct directory* exit_directory(struct directory* dir); ``` 接下来,我们需要实现一个函数来创建文件。该函数在指定的目录下创建一个文件,并返回文件指针,如下所示: ```c struct file* create_file(struct directory* dir, const char* name); ``` 接下来,我们需要实现一个函数来删除文件。该函数删除指定的文件,如下所示: ```c void delete_file(struct directory* dir, const char* name); ``` 接下来,我们需要实现一个函数来打开文件。该函数返回指定文件的指针,如下所示: ```c struct file* open_file(struct directory* dir, const char* name); ``` 接下来,我们需要实现一个函数来关闭文件。该函数释放指定文件的内存空间,如下所示: ```c void close_file(struct file* file); ``` 接下来,我们需要实现一个函数来文件。该函数返回指定文件的内容,如下所示: ```c char* read_file(struct file* file); ``` 接下来,我们需要实现一个函数来写文件。该函数将指定内容写入文件中,如下所示: ```c void write_file(struct file* file, const char* content); ``` 4. 实现代码 下面是一个简单的二级文件系统的实现代码,供参考: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #define MAX_SUBDIRS 10 #define MAX_FILES 10 struct file { char name[20]; int size; int type; char* content; }; struct directory { char name[20]; struct directory* parent; struct directory* subdirs[MAX_SUBDIRS]; struct file* files[MAX_FILES]; }; struct directory* init_fs() { struct directory* root = (struct directory*)malloc(sizeof(struct directory)); strcpy(root->name, "root"); root->parent = NULL; memset(root->subdirs, 0, sizeof(struct directory*) * MAX_SUBDIRS); memset(root->files, 0, sizeof(struct file*) * MAX_FILES); return root; } struct directory* create_directory(struct directory* parent, const char* name) { struct directory* dir = (struct directory*)malloc(sizeof(struct directory)); strcpy(dir->name, name); dir->parent = parent; memset(dir->subdirs, 0, sizeof(struct directory*) * MAX_SUBDIRS); memset(dir->files, 0, sizeof(struct file*) * MAX_FILES); int i; for (i = 0; i < MAX_SUBDIRS; i++) { if (parent->subdirs[i] == NULL) { parent->subdirs[i] = dir; break; } } return dir; } void delete_directory(struct directory* dir) { int i; for (i = 0; i < MAX_SUBDIRS; i++) { if (dir->subdirs[i] != NULL) { delete_directory(dir->subdirs[i]); } } for (i = 0; i < MAX_FILES; i++) { if (dir->files[i] != NULL) { free(dir->files[i]->content); free(dir->files[i]); } } free(dir); } struct directory* enter_directory(struct directory* parent, const char* name) { int i; for (i = 0; i < MAX_SUBDIRS; i++) { if (parent->subdirs[i] != NULL && strcmp(parent->subdirs[i]->name, name) == 0) { return parent->subdirs[i]; } } return NULL; } struct directory* exit_directory(struct directory* dir) { return dir->parent; } struct file* create_file(struct directory* dir, const char* name) { struct file* file = (struct file*)malloc(sizeof(struct file)); strcpy(file->name, name); file->size = 0; file->type = 1; file->content = NULL; int i; for (i = 0; i < MAX_FILES; i++) { if (dir->files[i] == NULL) { dir->files[i] = file; break; } } return file; } void delete_file(struct directory* dir, const char* name) { int i; for (i = 0; i < MAX_FILES; i++) { if (dir->files[i] != NULL && strcmp(dir->files[i]->name, name) == 0) { free(dir->files[i]->content); free(dir->files[i]); dir->files[i] = NULL; break; } } } struct file* open_file(struct directory* dir, const char* name) { int i; for (i = 0; i < MAX_FILES; i++) { if (dir->files[i] != NULL && strcmp(dir->files[i]->name, name) == 0) { return dir->files[i]; } } return NULL; } void close_file(struct file* file) { free(file->content); free(file); } char* read_file(struct file* file) { return file->content; } void write_file(struct file* file, const char* content) { file->size = strlen(content); file->content = (char*)malloc(file->size + 1); strcpy(file->content, content); } int main() { struct directory* root = init_fs(); struct directory* dir1 = create_directory(root, "dir1"); struct file* file1 = create_file(dir1, "file1"); write_file(file1, "hello world!"); printf("%s\n", read_file(file1)); delete_file(dir1, "file1"); delete_directory(dir1); return 0; } ``` 5. 总结 以上就是一个简单的二级文件系统的设计实现,该文件系统可以实现基本的文件管理功能。当然,实际的文件系统要比这个复杂得多,需要考虑更多的细节和异常情况,例如文件的权限、文件的锁定、文件的恢复等等。但是,以上的代码可以作为一个基础来学习和理解文件系统的设计和实现。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值