当前位置: 首页 > news >正文

苏州新区做网站公司58同城网站建设思路

苏州新区做网站公司,58同城网站建设思路,工控界面设计,wordpress实现多重筛选上篇文章:Linux操作系统2-进程控制3(进程替换,exec相关函数和系统调用)_execv系统调用-CSDN博客 本篇代码Gitee仓库:myLerningCode 橘子真甜/linux学习 - 码云 - 开源中国 (gitee.com) 本篇重点:C语言基础IO与系统调用 目录 一.…

上篇文章:Linux操作系统2-进程控制3(进程替换,exec相关函数和系统调用)_execv系统调用-CSDN博客

本篇代码Gitee仓库:myLerningCode · 橘子真甜/linux学习 - 码云 - 开源中国 (gitee.com)

本篇重点:C语言基础IO与系统调用

目录

一. 文件相关知识

二. C语言的文件操作 

2.1 fopen

2.2 fclose 

2.3 fread

2.4 fwrite

2.5 fprintf

2.6 举例代码

三. 文件相关的IO系统调用

3.1 open

3.2 close 

3.3 write

3.4 read

3.5 举例代码操作 

四. OS是如何管理被打开的文件?

4.1 文件fd

 五. 下篇重点: 文件fd, Linux下一切皆文件


一. 文件相关知识

        在基础指令这篇文章 Linux基础1-基本指令2(你真的了解文件吗?)-CSDN博客 中,我们提到了文件的相关命令。总结一下

1 一个空文件也需要占用空间

2 文件 = 文件内容 + 文件属性

3 文件操作 = 操作文件内容 + 操作文件属性

4 我们使用文件路径+文件名标记一个文件

5 进程想要访问一个文件必须要先通过OS打开这个文件

        C语言为用户提供了文件操作,C++也有相关的文件操作。像这些语言级别的库函数提供的文件操作,都是对OS提供的文件操作系统调用的封装。所以,学习系统调用提供的文件操作有利于我们掌握语言级的文件操作

二. C语言的文件操作 

        C语言中的库函数为我们提供了很多操作文件的函数:fopen,fclose,fwrite,fread,fprintf,fscanf...等。

2.1 fopen

        fopen用于打开一个文件,其函数原型如下:

//所需头文件
#include <stdio.h>//函数原型
FILE* fopen(const char* filename, const char* mode);//filename,打开文件的路径。直接写名字默认在当前路径下查找//mode,打开的方式
"r" 只读方式打开
"w" 只写方式打开,默认会清空文件中的内容
"a" 只写,写的方式是追加
"b" 以二进制方式打开,一般配合r和w使用
"W+" 读写,没有文件会创建,写方式是清空文件从头开始写
"r+" 读写,从头开始写文件
"a+" 读写,追加写

2.2 fclose 

        用于关闭一个打开的文件

//函数原型
int fclose(FILE* stream);//关闭stream这个文件流(被fopen打开的文件流)

2.3 fread

        用于读一个文件中的数据

//函数原型
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);ptr: 读取的文件存放在内存中的位置
size:读取文件中元素大小(以字节为单位)
nmemb:读取文件元素的数量
stream:读取文件的文件流(你要读取的文件)

2.4 fwrite

size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);//参数和fread类似//只是功能是将ptr写入到stream这个文件流中

2.5 fprintf

//函数原型
int fprintf(FILE *stream, const char *format, ...);//用法和printf一样,不过是将数据写入到stream这个文件流中

其他文件操作都和上述文件操作类似。具体内容可以查找man手册

2.6 举例代码

        用一段代码来举例这些操作的用法

test.c

#include <stdio.h>
#include <string.h>
#include <stdlib.h>#include <unistd.h>
#define MY_FILENAME "log.txt"int main()
{// 1.写入数据FILE *fp = fopen(MY_FILENAME, "w");if (fp == NULL){// 打开文件失败perror("fopen");}// 2.使用fwrite写数据,写入三行 Hello worldconst char *buffer = "Hello World!\n";fwrite(buffer, sizeof(char), strlen(buffer), fp);fwrite(buffer, sizeof(char), strlen(buffer), fp);fwrite(buffer, sizeof(char), strlen(buffer), fp);// 3. 关闭文件fclose(fp);fp = NULL;return 0;
}

Makefile

test:test.cgcc -o $@ $^ -std=c99.PHONY:clean
clean:rm -rf test log.txt

 测试结果如下:

修改 log.txt 和 test.c 进行读取数据 

log.txt

Hello World!
Hello World!
Hello World!
YZC yzc 
abc 123
156 1sg 45qe1r 5h@#@ ^% 56 @# ^re8 5qh qer56h 16 32`7 tr314yt 9bm    v891-3 

test.c

#include <stdio.h>
#include <string.h>
#include <stdlib.h>#include <unistd.h>
#define MY_FILENAME "log.txt"int main()
{// 1.读取数据FILE *fp = fopen(MY_FILENAME, "r");if (fp == NULL){// 打开文件失败perror("fopen");}// 2.使用fread写数据,写入三行 Hello worldchar buffer[200];fread(buffer, sizeof(char), 200, fp);buffer[strlen(buffer) - 1] = '\0';  //将最后的'\n'变为'\0'printf("%s\n", buffer);// 3. 关闭文件fclose(fp);fp = NULL;return 0;
}

 测试结果:

      注意C语言的字符串默认在结尾有一个'0',而文本文件中末尾并没有'\0'。所以我们使用C语言接口读取文件后,如果是字符串,需要在末尾加上'\0' 

三. 文件相关的IO系统调用

3.1 open

        打开文件的系统调用

//所需头文件
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>//函数原型
int open(const char *pathname, int flags)                 //用于打开已经创建的文件
int open(const char *pathname, int flags, mode_t mode)    //用于打开和创建文件    //pathname 打开文件的名字
//flags    打开文件的方式
//mode     创建文件时候文件的权限//常见的flag
O_RDONLY 表示只读
O_WRONLY 只写
O_WRONLY 读写
O_APPEND 追加写
O_CREAT  没有这个文件要创建文件
O_TRUNC  打开文件的时候清空文件内容

3.2 close 

        关闭文件fd的系统调用

//文件关闭
#include <unistd.h>//函数原型
int close(int fildes);

3.3 write

        向文件写入数据

//头文件
#include <unistd.h>//函数原型
ssize_t write(int fd, const void *buf, size_t count);//fd 写入的文件fd//buf 要写的数据缓冲区来源//count 写入的字节个数//返回值,成功写入,返回写入的字符数,失败返回-1

buf是void* 的原因:在系统看来,任何数据都是二进制

3.4 read

        从文件中读取数据

//头文件
#include <unistd.h>//函数原型
ssize_t read(int fd, void *buf, size_t count)//将fd文件中的count字节数量的数据读取到buf中//返回0表示读取到文件结尾

3.5 举例代码操作 

 

#include <stdio.h>
#include <string.h>
#include <stdlib.h>#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#define MY_FILENAME "log.txt"int main()
{// 1.打开文件,方式是读写,没有文件创建,清空文件从头开始写。创建的文件权限是0666umask(0); // 清空系统的umaskint fd1 = open(MY_FILENAME, O_WRONLY | O_CREAT | O_TRUNC, 0666);// 如果写入失败if (fd1 < 0){perror("open");return -1;}// 2.写入数据char buffer[64];int cnt = 5;while (cnt){sprintf(buffer, "YZC Hello World [%d]\n", cnt--); // 将数据写入缓冲区write(fd1, buffer, strlen(buffer));             // 向文件写入数据不需要添加'\0'}// 3.关闭文件描述符fdclose(fd1);// 4.读取这些数据int fd2 = open(MY_FILENAME, O_RDONLY);// 如果文件打开错误if (fd2 < 0){perror("open");return -1;}// 读取文件的时候,buffer最多读取sizeof(buf)个数据,由于有'\0'。所以要-1char *buf[64];ssize_t num = read(fd2, buf, sizeof(buf) - 1);printf("%s", buf);// 关闭文件close(fd2);return 0;
}

测试结果:

 语言级别的IO操作库函数都是对系统调用IO操作的封装

四. OS是如何管理被打开的文件?

        我们知道,OS通过PCB来管理进程。在OS中有很多进程,这些进程也会打开很多的文件。那么OS是如何管理这些被打开的文件的?

        OS为了管理被打开的文件,创建对应的内核数据结构 struct_file。这个结构体包含了文件的大量属性。

4.1 文件fd

         文件fd是什么东西?我们打印出来看看

#include <stdio.h>
#include <string.h>
#include <stdlib.h>#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#define MY_FILENAME "log.txt"int main()
{umask(0); //清楚umask码,仅仅修改该进程创建的文件int fd1 = open(MY_FILENAME, O_WRONLY | O_CREAT | O_APPEND, 0666);int fd2 = open(MY_FILENAME, O_WRONLY | O_CREAT | O_APPEND, 0666);int fd3 = open(MY_FILENAME, O_WRONLY | O_CREAT | O_APPEND, 0666);int fd4 = open(MY_FILENAME, O_WRONLY | O_CREAT | O_APPEND, 0666);int fd5 = open(MY_FILENAME, O_WRONLY | O_CREAT | O_APPEND, 0666);printf("fd1:%d\n",fd1);  printf("fd2:%d\n",fd2);  printf("fd3:%d\n",fd3);  printf("fd4:%d\n",fd4);  printf("fd5:%d\n",fd5);  close(fd1);close(fd2);close(fd3);close(fd4);close(fd5);return 0;
}

fd为什么从3开始?

        因为C语言会默认打开三个输入输出流,stdin, stdout, stderr。

        即标准输入,标准输出,标准错误。它们占用了0 1 2 

通过stdin这个文件的结构体中的 _fileno 即可获取fd

#include <stdio.h>
#include <string.h>
#include <stdlib.h>#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#define MY_FILENAME "log.txt"int main()
{umask(0); //清楚umask码,仅仅修改该进程创建的文件int fd1 = open(MY_FILENAME, O_WRONLY | O_CREAT | O_APPEND, 0666);int fd2 = open(MY_FILENAME, O_WRONLY | O_CREAT | O_APPEND, 0666);int fd3 = open(MY_FILENAME, O_WRONLY | O_CREAT | O_APPEND, 0666);int fd4 = open(MY_FILENAME, O_WRONLY | O_CREAT | O_APPEND, 0666);int fd5 = open(MY_FILENAME, O_WRONLY | O_CREAT | O_APPEND, 0666);printf("stdin->fd [%d]\n",stdin->_fileno);  printf("stdout->fd [%d]\n",stdout->_fileno);  printf("stderr->fd [%d]\n",stderr->_fileno);  printf("fd1:%d\n",fd1);  printf("fd2:%d\n",fd2);  printf("fd3:%d\n",fd3);  printf("fd4:%d\n",fd4);  printf("fd5:%d\n",fd5);  close(fd1);close(fd2);close(fd3);close(fd4);close(fd5);return 0;
}

测试结果如下:

         这些数字其实是一个数字的下标,在PCB中有一个指针数组 (称为文件描述符表)。这个指针数组存放的是指向struct_file这个文件管理的内核数据结构。

        进程通过fd这个数组下标就能够访问文件结构体!

具体关系可见下图:

 

 五. 下篇重点: 文件fd, Linux下一切皆文件

http://www.yayakq.cn/news/771344/

相关文章:

  • 建网站免费软件专门做特医食品的网站
  • 网站建设执招标评分表官方网站下载穿越火线
  • 设计培训网站建设精简wordpress头部信息
  • 龙华网站建设推广外包网站交互界面
  • 新手学做网站从哪里开始河北农业建设信息网站
  • 开设一个网站的费用wordpress建站优化
  • 个人工商注册查询网站网站 tag标签
  • 营销网站建设文章学计算机的毕业后可以找什么工作
  • 青岛网站设计公司哪家好自己电脑做采集网站
  • 做网站都可以用什么框架网络营销平台策略
  • 如何做简洁网站制作网站软件不懂代码可以制作吗
  • h5类型的网站是怎么做的如何修改上线网站
  • 凡科建站代理商wordpress 电子书插件
  • 天翼云主机怎么建设网站闸北微信网站建设
  • 凡科建站的网址一级消防工程师考试难度有多大
  • 音乐网站开发编程语言网站的友情链接怎么做
  • 网站创建风格杭州网站关键词排名优化
  • 网站设计 英文山东好的网站建设排行榜
  • 给人做ppt的网站化妆品公司网站建设方案
  • 攀枝花城市建设网站阿里云服务器是干什么用的
  • 松桃和兴建设公司网站网站建设完成报告
  • 做网站要哪些架包wordpress多站点 用户
  • 企业网站手机端模板下载鸿运通网站建设
  • 公司网站建设属于什么职位手工制作冰墩墩
  • 大学生兼职网站开发网页打不开怎么办页面无法显示
  • 网站开发模块查相似分公司vi设计
  • 河北省城乡和住房建设厅网站潍坊营销型网站
  • 无人机东莞网站建设电力行业网站建设
  • 哈尔滨企业建站零基础可以学平面设计吗
  • 东山县建设局网站wordpress网站如何添加内链