👍作者主页:进击的1++
🤩 专栏链接:【1++的Linux】
文章目录
- 一,初识文件
- 二,文件接口
一,初识文件
文件就是文件内容+属性。因此对文件的操作无非就是对文件内容的操作和对文件属性的操作。
我们访问文件,都是经过代码–>编译–>运行–>访问文件。这样的步骤。也就是说访问文件本质是进程在进行访问。
文件都是在硬件中放着,向硬件中访问与写入,只有操作系统才有这样的权力。我们普通用户也想写入,只有通过OS提供的接口来进行写入。
我们想想在语言级别中我们是如何对文件进行访问与写入的?------都是通过封装的文件相关的函数就行操作,那为什么不知直接用系统相关的调用函数呢?
原因有如下两点;
- 不同OS的系统调用函数不同,如果我们在代码中直接用了某个OS提供的系统调用函数,那么在其他OS下,该代码将会出现错误。因此使用经过语言提供的文件操作函数,可以跨平台。跨平台的方法可以将所有平台的代码都实现一遍,然后经过条件编译,动态裁剪,从而拿到我们当前需要的代码。
- 系统调用接口是更为复杂的,因此语言级别的接口都会进行封装,使其更好用。
Linux下一切皆文件。
我们对文件的操作无非就是read/write 。站到进程的角度我们使用printf,打印东西到屏幕上就是一种写:将数据写到屏幕上;使用scanf,进行输入,就是一种读,从键盘中读取数据到变量中。
因此实际上显示器和键盘也是文件。
因此我们可以再来一个小总结:什么是文件呢?
站在系统的角度,能够被写入,或是被读取的 设备就叫文件。狭义来说:就是我们的磁盘文件。广义来说:我们的显示器,键盘,网卡等都是文件。
二,文件接口
#include<stdio.h>
#include<string.h>
int main()
{
FILE* fd=fopen("test.txt","w+");
fprintf(fd,"zkn\n");
char tmp[20];
rewind(fd);
fscanf(fd,"%s",tmp);
fclose(fd);
printf("%s\n",tmp);
return 0;
}
#include<stdio.h>
int main()
{
FILE* fd=fopen("test.txt","w+");
char name[]={"zkn\n"};
fwrite(name,sizeof(char),sizeof(name),fd);
char tmp[10];
rewind(fd);//文件写入后再读的话需要将文件内部的位置指针指向开头。
fread(tmp,sizeof(char),sizeof(tmp),fd);
printf("%s",tmp);
fclose(fd);
return 0;
}
以上是我们在C语言中常用的文件操作。
下面展示系统的文件操作接口:
打开文件
其中flags代表的是打开的方式,mode代表若文件不存在,新创建文件的权限。
下面我们来详细说说flags。
flags为整型,但是实际上我们不能以整型去看待它,而是把它看作位图。也就是说它的每一位都代表了一种选择。
有如下例子:
#include<stdio.h>
#define ONE 0x1
#define TWO 0x2
#define THREE 0x3
void show(int flags)
{
if(flags& ONE) printf("one\n");
if(flags& TWO) printf("two\n");
if(flags& THREE) printf("three\n");
}
int main()
{
show(ONE);
printf("--------------------\n");
show(ONE|TWO);
printf("--------------------\n");
show(ONE|TWO|THREE);
return 0;
}
通过上述例子我们就能清楚的了解到flags的用法了。
写文件:
读文件
下面是系统文件调用接口的演示:
#include<stdio.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<string.h>
int main()
{
// int fd=open("test.txt",O_RDONLY|O_WRONLY|O_CREAT|O_APPEND,0666);
int fd=open("test.txt",O_RDONLY);
if(fd<0)
{
perror("open");
return 1;
}
const char *name="zkn\n";
//write(fd,name,strlen(name));//在写入时不需要把'\0‘也写入--因为那是C语言定义的结束标志,和系统无关.
char buffer[32];
memset(buffer,'\0',sizeof(buffer));//系统接口在读取时不会自己添加结束符.因此要我们自己添加。
read(fd,buffer,sizeof(buffer));
printf("%s",buffer);
close(fd);
return 0;
}
结果:
我们的fopen,fread,fwrite实际上都是调用了系统的这些接口,但是是经过了一些封装的,为了方便我们用户使用。像我们fopen函数中打开方式的参数 w,在系统调用这里则是:包含了读,写,默认清空文件,创建文件。这些参数进行或操作才能够有fopen中的w的功能。
新创建的文件会在当前路径下创建。那么什么叫当前路径呢?
就是进程运行时所处的工作路径
有如下例子:
我们在上一级路径下运行该程序。
我们发现其新建的文件也在次路径下,这也就证明了上述的结论。