zl程序教程

您现在的位置是:首页 >  系统

当前栏目

学习笔记——Linux的open、write、read、lseek、close函数

Linux笔记学习 函数 open Read Write CLOSE
2023-09-11 14:16:59 时间

前言

open、write、read、lseek、close函数是Linux的常用函数,是对文件的基本操作
下面展开罗列下

说明下,遇到函数不清楚,返回类型不明白,记得man下哦
man 1是普通的shell命令,比如ls
man 2是系统调用函数,比如open,write说明

可以看看基本命令
学习笔记——Linux常用命令(自己总结,没有花里胡哨)

接下来看看这几个函数

open函数

放个图,这是通过man手册看到的解释在这里插入图片描述
可以看到如果要使用open函数,必须包含这三个头文件

#include <sys/types.h>//这里提供类型pid_t和size_t的定义
#include <sys/stat.h>
#include <fcntl.h>

给出了定义

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

- const char *pathname,也就是文件路径,只写文件名默认在当前目录,否则你就写绝对路径
- int flags 是操作符,有三个权限,只能选择其一。
O_RDONLY 只读打
O_WRONLY 只写打
O_RDWR  可读可写打开    当我们附带了权限后,打开的文件就只能按照这种权限来操作。

下面几个是可选的操作
        O_CREAT 这个是创建文件操作,若文件不存在则创建它。使用此选项时,需要同时说明第三个参数mode,用mode说明文件的操作权限。
        O_EXCL 如果同时指定了O_CREAT,而文件已经存在,则返回-1报错。        
        O_APPEND 每次写时都加到文件的尾端。
        O_TRUNC 如果文件有内容,而且为只读或只写成功打开,则将其长度截短为0。
说到mode,补充一下(但是好像不太常用)
0755->即用户具有读//执行权限,组用户和其它用户具有读写权限;
0644->即用户具有读写权限,组用户和其它用户具有只读权限;
0600->仅拥有者具有文件的读取和写入权限
read可读4;write可写2;execute可执行1
比如我们经常看文件的属性-rw-r--r--这就是他的权限
O_CREAT需要配合mode使用,也就是说明文件的权限,比如fd = open("./file1",O_RDWR|O_CREAT,0600);
0600就是file1这个文件的可读可写权限

返回值。。。。打开成功,返回描述符,接下来可能对文件的读写等操作,打开失败返回-1
在这里插入图片描述
比如这样的例子

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
int main(){
        int fd;
//        char *buf = "handsomen\n";
        fd = open("./file1",O_RDWR);

        printf("%d\n",fd);
        printf("open succeed\n");
        if(fd == -1){
                fd = open("./file1",O_RDWR|O_CREAT,0600);
                printf("%d\n",fd);
                printf("create succeesd\n");
        }
//      ssize_t write(int fd, const void *buf, size_t count);
//        write(fd,buf,strlen(buf));
        close(fd);
}

如果文件存在那么就直接返回打印fd,并输出open succeed
文件不存在,返回-1,判断如果==-1,就创建权限为0600的文件,并返回打印fd,输出create succeesd
在这里插入图片描述

write函数

功能:write()会把参数buf所指的内存写入count个字节到参数fd所指的文件内。

-  #include <unistd.h>  这是write必须包含的头文件
- ssize_t write(int fd, const void *buf, size_t count);这是格式
 write操作会把buf缓存的字节向fd标识的文件中写入count个字

fd是文件描述符号,所有打开文件都是通过fd引用。当我们创建一个文件时,内核向进程返回一个文件描述符(非负数);读写时,用open返回的文件描述符标识文件,给write、read等操作传递fd参数。

*buf: 写入的数据的首地址
count: 写入数据个数
返回值:写入成功返回写入的个数,失败返回-1

int main(){
	int fd;
	char *buf = "handsomen\n";
	fd = open("./file1",O_RDWR);
	
	printf("%d\n",fd);
	printf("open succeed\n");
	if(fd == -1){
		fd = open("./file1",O_RDWR|O_CREAT,0600);
		printf("%d\n",fd);
		printf("create succeesd\n");
	}
//	ssize_t write(int fd, const void *buf, size_t count);
	int n_write = write(fd,buf,strlen(buf));
	close(fd);
}

fd标识file1,向file中写入buf中的内容,写入的长度是strlen(buf),也就是写入整个buf长度,最后可以在file1中发现handsomen

read函数

功能:从打开的fd设备或文件中读取count个字节到buf中

- #include <unistd.h

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

fd:文件描述符
*buf:读出数据的首地址
count:读出数据的个数

和write大同小异,都是通过fd执行对文件的操作

#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 *buf = "handsomen\n";
	fd = open("./file1",O_RDWR);
	
	printf("%d\n",fd);
	printf("open succeed\n");
	if(fd == -1){
		fd = open("./file1",O_RDWR|O_CREAT,0600);
		printf("%d\n",fd);
		printf("create succeesd\n");
	}
//	ssize_t write(int fd, const void *buf, size_t count);
	int n_write = write(fd,buf,strlen(buf));
	char *readBuf;
	readBuf = (char *)malloc(sizeof(buf)*n_write);
//这里给readbuf开辟空间
//	 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);
	int n_read = read(fd,readBuf,n_write);
	printf("read%d byte,context :%s\n",n_read,readBuf);
	close(fd);
}

看看最后的结果,向里面写入了10个字节,读出来数据(这里用到了lseek)
在这里插入图片描述

lseek函数

lseek光标定位
在这里插入图片描述

       #include <sys/types.h>
       #include <unistd.h>

       off_t lseek(int fd, off_t offset, int whence);

fd : 文件描述符
offset :偏移量
whence :
SEEK_SET: 参数offset即为新的读写位置
SEEK_CUR: 当前位置往后增加offset个偏移量
SEEK_END: 将读写位置指向文件尾后再增加offset个位移量

当whence值为SEEK_CUR或SEEK_END时,参数offset允许负值的出现。

举个栗子

int main(){
	int fd;
	char *buf = "handsomen\n";	
	fd = open("./file1",O_RDWR);
	int n_lseek = lseek(fd,0,SEEK_END);
	printf("%d\n",n_lseek);
	close(fd);
}

我们open文件之后,光标是停留在file1文件的开头,那么我们用lseek的SEEK_END指向末尾,偏移0,这样就读出了文件数据的大小。

如果我们刚刚write file1,光标会停留在末尾,也就是handsomen的n后面,这时候需要用SEEK_SET,偏移0,让光标恢复到开头,然后再读取

close函数


       #include <unistd.h>//头文件

    格式   int close(int fd);

这个没啥特别的,就是执行完open等一系列的操作之后,关闭文件,如果不关闭有时候会出现bug
记得open之后必有close

总结

Linux文件常用的函数API
open打开文件

write写入操作

read读取操作

lseek光标定位

close关闭文件