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

网站优怎么做百度推广官方投诉电话

网站优怎么做,百度推广官方投诉电话,网站开发所有工具多大,网页制作流程包括哪些理解 "文件" 狭义理解 文件在磁盘里 磁盘是永久性存储介质,因此文件在磁盘上的存储是永久性的 磁盘是外设(即是输出设备也是输入设备) 磁盘上的文件 本质是对文件的所有操作,都是对外设的输入和输出 简称 IO 广义理解…

理解 "文件"

狭义理解

文件在磁盘里
磁盘是永久性存储介质,因此文件在磁盘上的存储是永久性的
磁盘是外设(即是输出设备也是输入设备)
磁盘上的文件 本质是对文件的所有操作,都是对外设的输入和输出 简称 IO

广义理解

Linux 下一切皆文件(键盘、显示器、网卡、磁盘…… 这些都是抽象化的过程)

文件操作的归类认知

对于 0KB 的空文件是占用磁盘空间的
文件是文件属性(元数据)和文件内容的集合(文件 = 属性(元数据)+ 内容)
所有的文件操作本质是文件内容操作和文件属性操作

系统角度

对文件的操作本质是进程对文件的操作
磁盘的管理者是操作系统
文件的读写本质不是通过 C 语言 / C++ 的库函数来操作的(这些库函数只是为用户提供方便),而是通过文件相关的系统调用接口来实现的

C语言的fopen,fwrite,fread是库函数并不是系统调用,这三个接口都是封装了操作系统底层的系统调用

回顾C文件接口

打开文件

#include <stdio.h>
int main()
{FILE *fp = fopen("myfile", "w");if(!fp){printf("fopen error!\n");}while(1);fclose(fp);return 0;
}

写文件

#include <stdio.h>
#include <string.h>
int main()
{FILE *fp = fopen("myfile", "w");if(!fp){printf("fopen error!\n");}const char *msg = "hello bit!\n";int count = 5;while(count--){fwrite(msg, strlen(msg), 1, fp);}fclose(fp);return 0;
}

读文件

#include <stdio.h>
#include <string.h>
int main()
{FILE *fp = fopen("myfile", "r");if(!fp){printf("fopen error!\n");return 1;}char buf[1024];const char *msg = "hello bit!\n";while(1){//注意返回值和参数,此处有坑,仔细查看man⼿册关于该函数的说明 ssize_t s = fread(buf, 1, strlen(msg), fp);if(s > 0){buf[s] = 0;printf("%s", buf);}if(feof(fp)){break;}}fclose(fp);return 0;
}

管理文件

一个进程可以打开多个文件,所以系统中存在大量被打开或正要关闭的文件,所以操作系统需要管理文件,先描述,再组织!!!

操作系统通过一个结构体struct file来管理文件,在文件被打开的时候就会创建一个struct file,其中存放着文件的各种属性,结构体之间互相链接形成链表,所以操作系统对文件的管理就转换成了对链表的管理

task_struct中不止存在页表,还存在着一个文件描述符表struct files_struct,其中存放着一个  struct file数组,数组的每一个的下标都链接着一个文件的地址,系统就通过数组来管理每一个进程打开的文件。

相对应一个文件也可以被多个进程打开,那么关闭文件是否会对进程造成影响,毕竟进程是具有独立性的,而struct file使用和智能指针类似的做法,就是引用计数,只有计数为0的时候才会真正关闭文件

文件的内容会加载到文件缓冲区,文件的属性会加载到struct file

系统文件 I/O

初识标志位

打开文件的方式不仅仅是 fopen,ifstream 等流式,语言层的方案,其实系统才是打开文件最底层的方案。不过,在学习系统文件 IO 之前,先要了解下如何给函数传递标志位,该方法在系统文件 IO 接口中会使用到:

#include <stdio.h>
#define ONE 0001 //0000 0001
#define TWO 0002 //0000 0010
#define THREE 0004 //0000 0100
void func(int flags) {if (flags & ONE) printf("flags has ONE! ");if (flags & TWO) printf("flags has TWO! ");if (flags & THREE) printf("flags has THREE! ");printf("\n");
}
int main() {func(ONE);func(THREE);func(ONE | TWO);func(ONE | THREE | TWO);return 0;
}

通过这个代码能够了解标志位的作用

状态表示:每个标志位都能独立地表示一种状态。在这个例子中,ONE、TWO 和 THREE 分别代表不同的状态。

状态组合:通过按位或运算符 | 可以把多个标志位组合起来,以此表示多种状态的组合。

状态检查:借助按位与运算符 & 能够检查某个标志位是否被设置,从而依据不同的状态执行不同的操作。

系统调用读文件

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
int main()
{int fd = open("myfile", O_RDONLY);if(fd < 0){perror("open");return 1;}const char *msg = "hello bit!\n";char buf[1024];while(1){ssize_t s = read(fd, buf, strlen(msg));//类⽐write if(s > 0){printf("%s", buf);}else{break;}}close(fd);return 0;
}

系统调用写文件

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
int main()
{umask(0);int fd = open("myfile", O_WRONLY|O_CREAT, 0644);if(fd < 0){perror("open");return 1;}int count = 5;const char *msg = "hello bit!\n";int len = strlen(msg);while(count--){write(fd, msg, len);//fd: 后⾯讲, msg:缓冲区⾸地址, len: 本次读取,期望写⼊多少个字节的数据。 返回值:实际写了多少字节数据 }close(fd);return 0;
}

接口认识

open
int open(const char *pathname, int flags);
int open(const char *pathname, int flags, mode_t mode);

第一个参数是文件,第二个参数是标志位 ,第三个参数表示新创建文件的权限,如果新创建的文件不带mode会造成新创建的文件权限位乱码

通过使用标志位用偶有效减少传参的个数

open标志位介绍

O_RDONLY:以只读模式打开文件。文件只能被读取,不能进行写入操作
O_WRONLY:以只写模式打开文件。文件只能被写入,不能进行读取操作
O_RDWR:以读写模式打开文件。文件既可以被读取,也可以被写入
O_CREAT:如果文件不存在,则创建该文件。使用此标志位时,需要提供第三个参数 mode 来指定新文件的权限。
O_EXCL:和 O_CREAT 一起使用时,如果文件已经存在,则 open 调用会失败并返回 -1,同时将 errno 设置为 EEXIST。这可用于确保文件是新创建的。
O_TRUNC:如果文件存在且以可写模式打开,则将文件长度截断为零,即清空文件内容
O_APPEND:以追加模式打开文件。每次写操作都会将数据追加到文件末尾,而不是覆盖原有内容
O_NONBLOCK:以非阻塞模式打开文件。在进行读写操作时,如果没有数据可读或无法立即写入数据,函数不会阻塞,而是立即返回 -1,同时将 errno 设置为 EAGAIN 或 EWOULDBLOCK。这在处理多个文件描述符或需要异步操作时非常有用

而标志位的组合使用|

write
ssize_t write(int fd, const void *buf, size_t count);

第一个参数是文件操作符,第二个参数是写入文件的内容,第三个参数是需要写入的字节数

read 
ssize_t read(int fd, void *buf, size_t count);

第一个参数是文件操作符,第二个参数是存放读到的数据,第三个参数是读入的字节数

文件操作符

write,read的第一个参数都是fd,fd就是文件操作符

操作系统只认fd,那么fd是什么呢?在文件描述符表中存在struct file数组,fd就是数组的下标。

当我们打开多个文件的时候,查看他们的fd,会发现fd是从3开始的。这是由于数组中默认的0,1,2号下标分别是标准输入,标准输出,标准错误。

fd的数据是从小到大的,只要前面有多余的位置,系统就会将文件分配到靠前的下标

open的时候就会找到进程的文件描述符表中的数组,找到一个未被使用过的位置,将struct file的地址填入其中,fd就是数组的下标

read就是用fd找到数组的下标,访问对应文件的地址,从文件缓冲区中将数据拷贝到buffer,文件缓冲区的数据是由磁盘中文件的内容预加载到缓冲区中。

重定向

Linux中存在函数dup2,用于复制文件描述符

int dup2(int oldfd, int newfd);

oldfd:需要被复制的源文件描述符。
newfd:复制到的目标文件描述符。如果newfd已经打开,会先将其关闭。

使用dup2会将newfd位置的文件覆盖到oldfd上

可以通过dup2来替换标准输入,标准输出来实现重定向操作。

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include<unistd.h>
int main()
{int fd = open("test.txt", O_RDWR);dup2(fd,1);close(fd);printf("fd: %d\n", fd);return 0;
}

当我们将文件夹中的test.txt替换掉标准输出,此时使用printf, 则不会将内容输出到显示器上,而是将内容输出到test.txt中

操作系统只认识fd,printf就是为了往stdout中输出内容,但是stdout被关闭,此时fd为1的文件是log.txt,printf输出的内容就会输出到log.txt中

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include<unistd.h>
int main()
{int fd = open("test.txt", O_RDWR);dup2(fd,0);close(fd);char s[100];scanf("%s",s);printf("%s\n",s);return 0;
}

将test.txt文件替换标准输入文件,此时scanf一般是从键盘上读取数据,此时就只能从test.txt中读取数据,将test.txt的数据填写到s中。

操作系统只认fd,scanf就是从键盘中读取数据,但是标准输入被关闭,此时fd为0的文件是test.txt,此时scanf就会从 test.txt中读取数据

通过上面两端代码可以大致了解重定向的原理,就是将文件进行替换,从而将一下本该输出到显示屏中的数据输出到其他文件中,将从键盘中读取的数据转换成从其他文件中读取数据 

正确的重定向操作方法 

例如存在一个文件:log.txt,需要将原本输出到显示屏的数据输出到log.txt中

ls -l 1 > log.txt

将原本输出到1号文件的内容输出到log.txt中 ,而1号文件就是stdout

#include<cstdio>
#include<iostream>
using namespace std;
int main()
{cout<<"hellocout"<<endl;cerr<<"hellocerr"<<endl;return 0;
}

当我们使用这段代码重定向到一个文件时,cerr的内容并不会重定向到文件,而是输出在显示屏上,这是由于cerr对应的文件时stderr,它的fd为2,而默认的重定向只有1

所以可以通过将1重定向到log.txt,2追加重定向到log.txt

./a 1 > log.txt 2 >> log.txt

此时cout和cerr的内容就都输出到log.txt中了 

也可以将标准错入重定向到标准输出的目标位置,&1 表示「当前标准输出的目标位置」

./a 1 > log.txt 2>&1

效果与第一种一样 

理解“一切皆文件”

首先,在 Windows 中是文件的东西,它们在 Linux 中也是文件;其次一些在 Windows 中不是文件的东西,比如进程、磁盘、显示器、键盘这样硬件设备也被抽象成了文件,你可以使用访问文件的方法访问它们获得信息;甚至管道,也是文件;将来我们要学习网络编程中的 socket(套接字)这样的东西,使用的接口跟文件接口也是一致的。

这样做最明显的好处是,开发者仅需要使用一套 API 和开发工具,即可调取 Linux 系统中绝大部分的资源。举个简单的例子,Linux 中几乎所有读(读文件,读系统状态,读 PIPE)的操作都可以用 read 函数来进行;几乎所有更改(更改文件,更改系统参数,写 PIPE)的操作都可以用 write 函数来进行。

在操作系统中,每个外设都有一套属于自己的读写操作。操作系统中的struct file的内容中存在函数指针,他们会指向对应外设的读写操作,而每个函数指针的命名,参数,都一样

一切皆文件,是进程认为一切皆文件,进程中存储着文件描述符表,文件描述符表指向struct file,从硬件角度上来看,struct file的函数指针指向硬件的读写操作,所以管理好文件也就能管理好硬件,进程无需接触到硬件,只需接触到struct file即可

上图中的外设,每个设备都可以有自己的 read、write,但一定是对应着不同的操作方法!!但通过struct file 下 file_operation 中的各种函数回调,让我们开发者只用 file 便可调取 Linux 系统中绝大部分的资源!!这便是 “linux 下一切皆文件” 的核心理解。 

缓冲区 

什么是缓冲区

缓冲区就如同日常中的快递站,可以帮助我们在空闲时间再去拿快递,而非在快递送到家门口的时候无论在做任何事情都要回去拿快递,这样也严重影响了快递员的效率

缓冲区是内存空间的一部分。也就是说,在内存空间中预留了一定的存储空间,这些存储空间用来缓冲输入或输出的数据,这部分预留的空间就叫做缓冲区。缓冲区根据其对应的是输入设备还是输出设备,分为输入缓冲区和输出缓冲区。

可以查看Linux中的FILE结构体

它的指针就指向了缓冲区的位置

为什么要引入缓冲区机制

系统调用也是有成本的,系统调用是需要操作系统进行操作的,而操作系统平时需要进行大量的资源管理,如果没有缓冲区,当我们进行文件写入时,操作系统无论做什么事情都需要停下来进行写入操作

读写文件时,如果不会开辟对文件操作的缓冲区,直接通过系统调用对磁盘进行操作 (读、写等),那么每次对文件进行一次读写操作时,都需要使用读写系统调用处理此操作,即需要执行一次系统调用,执行一次系统调用将涉及到 CPU 状态的切换,即从用户空间切换到内核空间,实现进程上下文的切换,这将损耗一定的 CPU 时间,频繁的磁盘访问对程序的执行效率造成很大的影响。

为了减少使用系统调用的次数,提高效率,我们就可以采用缓冲机制。比如我们从磁盘里取信息,可以在磁盘文件进行操作时,可以一次从文件中读出大量的数据到缓冲区中,以后对这部分的访问就不需要再使用系统调用了,等缓冲区的数据取完后再去磁盘中读取,这样就可以减少磁盘的读写次数,再加上计算机对缓冲区的操作 快于对磁盘的操作,故应用缓冲区可 大提高计算机的运行速度。

又如,我们使用打印机打印文档,由于打印机的打印速度相对较慢,我们先把文档输出到打印机相应的缓冲区,打印机再自行逐步打印,这时我们的 CPU 可以处理别的事情。可以看出,缓冲区就是一块内存区,它用在输入输出设备和 CPU 之间,用来缓存数据。它使得低速的输入输出设备和高速的 CPU 能够协调工作,避免低速的输入输出设备占用 CPU,解放出 CPU,使其能够高效率工作。

缓冲类型

标准 I/O 提供了 3 种类型的缓冲区。

・全缓冲区:这种缓冲方式要求填满整个缓冲区后才进行 I/O 系统调用操作。对于磁盘文件的操作通常使用全缓冲的方式访问。

・行缓冲区:在行缓冲情况下,当在输入和输出中遇到换行符时,标准 I/O 库函数将会执行系统调用操作。当所操作的流涉及一个终端时(例如标准输入和标准输出),使用行缓冲方式。因为标准 I/O 库每行的缓冲区长度是固定的,所以只要填满了缓冲区,即使还没有遇到换行符,也会执行 I/O 系统调用操作,默认行缓冲区的大小为 1024。

・无缓冲区:无缓冲区是指标准 I/O 库不对字符进行缓存,直接调用系统调用。标准出错流 stderr 通常是不带缓冲区的,这使得出错信息能够尽快地显示出来。

缓冲区的工作

当使用printf/fprintf/fwrite等等的库函数进行文件操作的时候,数据并非直接写入到文件内核缓冲区中,c标准库中存在一个库缓冲区,使用库函数进行操作的时候,数据会先占时写入到库缓冲区中,直到某种条件的触发,会将fopen返回值中的fd找出来,通过fd进行系统调用,将库缓冲区的内容写到文件内核缓冲区中。

刷新缓冲区的条件

1.强制刷新

2.进程退出

3.刷新条件满足->(全缓冲,行缓冲,无缓冲)

http://www.dtcms.com/wzjs/268339.html

相关文章:

  • 南京网站制作公司排名厦门关键词排名推广
  • 南京企业网站百度权重等级
  • 兰州做网站怎么样百度代理公司怎么样
  • 网站没收录可以做排名阿里云建站
  • 无锡品牌学会网站建设友情链接交易网站
  • 萧山品牌网站建设个人免费网站建设
  • 网站建设优化公司哪家好营销策划方案内容
  • 七牛云存储 wordpress 没用长沙seo网站
  • 合肥做网站价格是多少网站建设的基本
  • 建设银行不招聘网站怎样做推广
  • 怎么做网页截图武汉百度网站优化公司
  • 苏州专业网站建设公司怎么做私人网站
  • 武进网站建设价格昆明做网站的公司
  • 做vue用哪个网站怎么在百度上面打广告
  • 做医药商城网站的公司吗众志seo
  • 数据库网站开发教程seo干什么
  • 数据中心idc机房西安百度seo推广电话
  • 口碑好的聊城网站建设全自动引流推广软件下载
  • 网站分析怎么写seo知识是什么意思
  • 设计色彩网站全网整合营销推广系统
  • 淄博做网站多少钱如何网上销售自己的产品
  • 长沙网站维护推广公司app主要做什么
  • 做网站推广怎么样成都网站seo外包
  • 阳江公司网站建设南昌seo
  • 网站制作网站模板今日国际新闻头条15条简短
  • 怎么在网站上添加广告代码谷歌搜索引擎镜像
  • 商务型网站国内搜索引擎
  • 嘉兴网站制作建设网站关键词怎么优化排名
  • 合肥 做网站网站开发软件
  • 海外做bt种子网站外贸推广公司