注:在我们不知道函数要用什么头文件的时候,可以用man指令在终端来查看函数的头文件和函数使用方法。看完之后按q就可以退出。例如如下:
Open函数的操作
参数:
pathname:指文件打开的路径。或者如果没有该文件,则为创建该文件的路径。
flags:(权限)打开文件时所需要的参数,可以用一个,也可以用多个。使用多个参数的时候用或运算符即"|"来使用
flags的参数列表:
O_RDONLY: 只读打开
O_WRONLY: 只写打开
O_RDWR: 读写均可打开)
注意:这三个参数中必须选取一个,且只能选一个。
O_CREAT :若文件不存在则创建它,使用此选项时,需要同时说明第三个参数mode,用其说明该新文件的存取许可权限,
O_EXCL:如果同时制定了OCREAT 而文件已经存在,则出错(即返回-1)
O_APPEND:每次写时都加到文件的尾端(这个与后续write函数的应用相关,若没有加上这个参数,则写入的write文本会覆盖文件中原本有的内容)
O_TRUNC:每次打开文件时,如果文件中本来是有内容的,而且为只读或只写,成功打开后,则将其文件中所有内容删除,光标指为0;
Mode:(只在创建文件的时候会有mode权限)一定是在flags中使用了O_CREAT标志。(即mode是用于创建文件的操作权限)mode记录创建的文件的访问权限。
读:4(r)
写:2(w)
可执行:1(x)
如果只读,就是4。可读可写就是6(4+2),可读可写可执行为7(4+2+1)因此类推
mode中有四个数字分别是给文件所有者的权限。
0600 第二个数字代表的是当前用户,第三个数字代表的是组用户,第四个数字代表的是其他组用户
OPEN()函数: 打开文件后,会返回fd一个数字。即代表了文件的描述符(文件的索引)。一般来说打开成功第一个文件返回的fd的值为3。打开失败返回-1。
如果打开失败说明并没有这个文件。如果你要创建这个文件,你就要使用
这个函数,即创建文件,mode是给这个创建的文件赋予权限。可读可写还是只读,只写。并且flags中要有O_CREAT这个参数,这样才可以创建这个文件
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<stdio.h>
int main()
{
int fd;
fd=open("./file1",O_RDWR);//如果当前文件夹中有fiel1这个文件,那么这个文件是以可读可写打开,并给一个返回值给fd
if(fd==-1){//如果打开失败会返回一个-1给fd
printf("文件打开失败\n");//打开失败证明没有这个文件
fd=open("./file1",O_RDWR|O_CREAT,0600);
//既然没有fiel1这个文件,那么就直接创建这个文件,所以falgs参数中必须有O_CREAT(即创建一个文件),因为有多个flags,所以用或|来一起使用。
//然后因为是创建文件,所以也会有mode这个参数,mode参数是给这个文件赋予可读可写可执行等权限
//记住,只要是创建文件,一定会有mode参数。6代表的是(4+2)即可读可写
if(fd>0){
printf("创建成功\n");
}
}
return 0;
}
那么为什么fd一开始只有3呢。是因为linux系统给标准化输入,标准化输出,和标准化错误分别设定了fd=0,fd=1,fd=2。
标准化输入是指用户通过键盘传入的内容。
标准化输出是指终端显示的内容。
#include<stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
int main()
{
int fd;
char readBuf[128];
int _read=read(0,readBuf,5);
/*文件描述符为0,意味着是标准化输入,由用户输入的内容为准。即将用户输入的五个字节读入
readBuf中(即缓存区)*/
int _write=write(1,readBuf,strlen(readBuf));
/*因为文字描述符为1,意味着是标准化输出,也就是终端上显示的画面。即把readBuf中
(即缓存区中)strlen(readBuf)个字节,写入标准化输出文件中。(即写入终端画面中)*/
printf("\n");
return 0;
}
若用户输入111,则终端显示111。
Close函数的使用:
close函数就是用于关闭文件。具体用法就是close(文件描述符)即可
注意:
1、在Linux中要操作一个文件,一般是先open打开一个文件,得到文件描述符,然后对文件进行读写操作(或其他操作),最后是close关闭文件即可。
2、强调一点:我们对文件进行操作时,一定要先打开文件,打开成功之后才能操作,如果打开失败,就不用进行后边的操作了,最后读写完成后,一定要关闭文件,否则会造成文件损坏。
3、文件平时是存放在块设备中的文件系统文件中的,我们把这种文件叫静态文件,当我们去open打开一个文件时,linux内核做的操作包括:内核在进程中建立一个打开文件的数据结构,记录下我们打开的这个文件;内核在内存中申请一段内存,并且将静态文件的内容从块设备中读取到内核中特定地址管理存放(叫动态文件)。
4、打开文件以后,以后对这个文件的读写操作,都是针对内存中的这一份动态文件的,而并不是针对静态文件的。当然我们对动态文件进行读写以后,此时内存中动态文件和块设备文件中的静态文件就不同步了,当我们close关闭动态文件时,close内部内核将内存中的动态文件的内容去更新(同步)块设备中的静态文件。
Write() 写文件的的操作
fd:文件描述符;
buf:无类型的指针(是一个缓冲区,里面包含一些内容);
count:写入文件的大小。
Write()函数的含义是,从buf中取出count个字节的数据,写入fd这个文件中。成功,返回值是写入的字节大小。失败,返回-1;
注意:当Write写完以后,光标是指向文件中最后一个位置。所以在不关闭文件的情况下然后又去读取文件中的内容时,read函数取不出来任何数据。这个时候可以把文件关闭,然后再重新打开文件。或者后续把光标移至文件的起始位置。
注意:如果本身文件中就有内容,然后直接进入写操作,如果写的文本大于原来文件的字节大小,那么原本文件的内容将全被覆盖,也就是若文件本身有100个字节,但是用户写入了10个字节。那么原本文件中前10个字节会被用户写的数据覆盖,后面的数据仍然是文件的内容
Read() 读文件的操作
fd :文件描述符;
buf :一个指针(缓冲区);
count:需要读取的字节大小。
Read与Write函数稍有不同,read函数是指,从fd这个文件中读取count个字节存入buf中。成功返回读取的大小,失败返回-1;
#include<stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
int main()
{
int fd;
int _write;
int _read;
char *readbuf;
char *buf="hello,world";
fd=open("./file1",O_RDWR);
if(fd==-1){
printf("打开失败\n");
fd=open("./file1",O_RDWR|O_CREAT,0600);
}
if(fd>0){
printf("打开成功\nfd为%d\n",fd);
}
// 往文件中写东西所需要的函数如下
// ssize_t write(int fd, const void *buf, size_t count);
_write= write(fd,buf,strlen(buf));
printf("写入成功!一共写入%d个字\n",_write);
// 打开文件后要关闭文件,close函数的用法
// #include <unistd.h>
// int close(int fd);
close(fd);//关闭文件后,光标指回文件的起始位置
fd=open("./file1",O_RDWR);
//读的函数
//ssize_t read(int fd, void *buf, size_t count);
readbuf=(char *)malloc(_write*sizeof(char)+1);
_read=read(fd,readbuf,_write);
close(fd);
return 0;
}
这个代码是针对不移动光标的做法,现在系统给了我们一个能控制光标的函数。那我们就使用这个函数重新来编写这一段代码。
LSEEK函数的使用
fd:文件描述符;
offset:偏移值:offset是相对于第三个参数的whence往后的偏移值大小。
如果whence是SEEK_SET,然后offset设置为0,就相当于光标对于文件头位置偏移0个位置大小。即光标指向文件的起始位置。
whence是固定点的位置;(SEEK_SET, SEEK_GND, SEEK_CUR)
文件头位置,文件尾位置,文件当前位置
lseek调用成功后,会返回光标针对文件头位置的大小的值。
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
int main()
{
int fd;
char writebuf[]="hello world";
char *readbuf;
fd = open("./file1",O_RDWR);
if(fd>0){printf("打开成功\n");}
// ssize_t write(int fd, const void *buf, size_t count);
int writefd=write(fd,writebuf,strlen(writebuf));
if(writefd>0){printf("写入成功\n");}
// off_t lseek(int fd, off_t offset, int whence);
lseek(fd,0,SEEK_SET);
// ssize_t read(int fd, void *buf, size_t count);
readbuf=(char *)malloc(writefd*sizeof(char)+1);
int readfd=read(fd,readbuf,writefd);
if(readfd>0){printf("阅读成功\n内容为%s\n",readbuf);}
close(fd);
return 0;
}