Linux文件打开open、文件写入write、文件读取read、文件关闭close、文件光标lseek、文件创建create和fopen系列对比

文件打开open、文件写入write、文件读取read、文件关闭close、文件光标lseek、文件创建create

文件一般流程是打开或者创建文档——编辑文档——保存文档——关闭文档。liunx文件操作所提供的api(Application Programming Interface,应用程序接口)有open、write、read、close、lseek、create等。

文件打开open

open头文件和函数

// open头文件
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
//open函数
int open(const char *pathname, int flags);
int open(const char *pathname, int flags, mode_t mode);
//open函数返回值,success 返回文件描述符, error 返回 -1
//pathname:文件路径名。例"./file1"
//flags:O_RDONLY 只读   		O_WRONLY 只写   		O_RDWR 	 可读可写可打开
//		O_CREAT  如果open文件不存在,则创建文件。
// 		O_EXCL	 如果同时指定了OCREAT,而文件已经存在,则open()出错,返回-1。	 
//		O_APPEND 每次文件写入加到文件尾部。
//		O_TRUNC  删去文件中原本的内容。
//mode:	一定是在flags中使用了O_CREAT标志,mode记录待创建的文件的访问权限。

mode的分类和加权数字表示

宏表示含义宏表示含义宏表示含义
S_IRUSR使用者可读权限S_IRGRP群组拥有读权限S_IROTH其他用户拥有读权限
S_IWUSR使用者可写权限S_IWGRP群组拥有写权限S_IWOTH其他用户拥有写权限
S_IXUSR使用者可执行权限S_IXGRP群组拥有执行权限S_IXOTH其他用户拥有执行权限

S_IRUSR、S_IWUSR、S_IXUSR比较常用

加权数字第一位第二位第三位
4使用者可读权限群组拥有读权限其他用户拥有读权限
2使用者可写权限群组拥有写权限其他用户拥有写权限
1使用者可执行权限群组拥有执行权限其他用户拥有执行权限

例如:0666,拥有4+2=6使用者可读、可写权限;拥有4+2=6群组可读、可写权限;拥有4+2=6其他用户可读、可写权限。

什么是文件描述符?简单来说就是描述和区分文件的一个标志。上面看出文件描述符是个int型。
什么是程序?什么进程?
1、程序是静态的概念,gcc xxx.c –o pro 磁盘中生成pro文件,叫做程序;
2、进程是程序的一次运行活动,通俗点意思是程序跑起来了,系统中就多了一个进程;
ps:图中fd为文件描述符,图中进程和原进程是一个意思,由于为让图结构看着清晰,取了原进程的名字。

进程文件1fd1...原进程文件2fd2...文件3open成功 返回 fd1open成功 返回 fd2open失败 返回 -1

open函数综合举例
int fd = open("./file1", O_RDWR|O_CREAT, 0600);open函数综合举例

文件写入write

write头文件和函数

// write头文件
#include <unistd.h>;
//write函数
ssize_t write(int fd, const void *buf, size_t count);
//函数含义:从buf中写count字节大小的数进入fd的文件里。
//返回 success 返回 整型数 = 写入的字节数; error 返回 -1

write函数综合举例:

	char *buf ="linux write";
	write(fd, buf, sizeof(buf));`write函数综合举例`

文件读取read

read头文件和函数

// read头文件
#include <unistd.h>;
//read函数
ssize_t read(int fd, const void *readbuf, size_t count);
//函数含义:从fd的文件中读出count字节大小的数进入readbuf。
//返回 success 返回 整型数 = 写入的字节数; error 返回 -1

read函数综合举例:

	read(fd, buf, sizeof(buf));`read函数综合举例`

文件关闭close

close头文件和函数

// close头文件
#include <unistd.h>;
//read函数
ssize_t close(int fd);
//函数含义:关闭fd文件。

close函数综合举例:

	close(fd);`close函数综合举例`

文件光标seek

每次读取或者写入后,光标的位置的位置不确定。为了确定光标位置,可以使用lseek()函数
lseek头文件和函数

// lseek头文件
#include <unistd.h>;
#include <sys/type.h>;
//lseek函数
off_t lseek(int fd, off_t offset, int whence);
//函数含义:依据whence的定位偏移offset的位数;
//whence:SEET_SET 文件头
//		  SEEK_CUR 当前光标位置
//		  SEEK_END 文件尾
//offset: offset 正数往后移,负数往前移
//返回 success 返回 当前光标位置与文件头偏移字节数; 失败 返回 -1

lseek函数综合举例:

	lseek(fd, 0, SEEK_END);`lseek函数综合举例`

文件创建create

create头文件和函数

// creat头文件
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
//creat函数
int creat(const char *pathname, mode_t mode);
//函数含义:依据whence的定位偏移offset的位数;
//pathname:文件路径名。例"./file1"
//返回 success 返回 文件标识符; 失败 返回 -1
宏表示含义
S_IRUSR使用者可读权限
S_IWUSR使用者可写权限
S_IXUSR使用者可执行权限
S_IRWXU使用者可读可写可执行权限

creat函数综合举例:

	creat(fd, S_IRWXU);`creat函数综合举例`

动态文件和静态文件

静态文件指的是存在磁盘中的文件。
动态文件指的是open打开静态文件后,Linux内核产生结构体,结构体中包含文件标识符fd、信息节点、buf等,然后close关闭,才可以变回静态文件。

ps:比较两个程序异同vimdiff 文件名 文件名

实战举例一:cp拷贝代码的编写

思路
1、打开src.c
2、读src.c到buf
3、打开des.c
4、写buf到des.c
5、close两个文件

#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 argc, char **argv)//argc是命令行总的参数个数
					//**argv=*argv[]是argc个参数,其中第0个参数是程序的全名,以后的参数命令行后面跟的用户输入的参数
{
        int fdSrc;//打开源文件文件标识符
        int fdDec;//打开目标文件文件标识符

        if(argc !=3){
                printf("param error\n");
                exit(-1);
        } 			//判断输入参数是否正确

        fdSrc=open(argv[1],O_RDWR,0600);

        int size = lseek(fdSrc,0,SEEK_END);  //计算文件大小
        lseek(fdSrc,0,SEEK_SET);			//重置文件光标

        char *readBuf=(char* )malloc(sizeof(char)*size + 8);

        int n_read=read(fdSrc,readBuf,size);
        fdDec=open(argv[2],O_RDWR|O_CREAT|O_TRUNC,0600);//创建可读可写可执行、删除原本文件内容

        int n_write = write(fdDec,readBuf,size);

        close(fdSrc);
        close(fdDec);
        return 0;

}

实战举例二:配置文件参数

思路:
1、找到a的位置
2、a往后移到b
3、修改b的内容

#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 argc, char **argv)
{
        int fdSrc;

        if(argc != 2){
                printf("param error\n");
                exit(-1);
        }

        fdSrc=open(argv[1],O_RDWR,0600);

        int size = lseek(fdSrc,0,SEEK_END);
        lseek(fdSrc,0,SEEK_SET);

        char *readBuf=(char* )malloc(sizeof(char)*size + 8);

        int n_read=read(fdSrc,readBuf,size);
        char *p = strstr(readBuf,"LENG=");//字符串查找函数
        if(p==NULL){
                printf("not found\n");
        }
        p=p+strlen("LENG=");			//字符串计算函数
        *p='5';

        lseek(fdSrc,0,SEEK_SET);
        int n_write = write(fdSrc,readBuf,size);

        close(fdSrc);
        return 0;

}

扩展知识——比较fopen系列与open系列函数区别

1、来源
open是UNIX系统调用函数(包括LINUX等),返回的是文件描述符(File Descriptor),它是文件在文件描述符表里的索引。
fopen是ANSIC标准中的C语言库函数,在不同的系统中应该调用不同的内核api。返回的是一个指向文件结构的指针
2、移植性
fopenC标准函数,因此拥有良好的移植性;而openUNIX系统调用,移植性有限。如windows下相似的功能使用API函数CreateFile。
3、适用范围
open返回文件描述符,而文件描述符是UNIX系统下的一个重要概念,UNIX下的一切设备都是以文件的形式操作。当然包括操作普通正规文件(Regular File)。fopen是用来操纵普通正规文件(Regular File)的。
4、文件IO层次
低级和高级的简单区分标准是:谁离系统内核更近。低级文件IO运行在内核态,高级文件IO运行在用户态。open属于低级IO函数,fopen属于高级IO函数。
5、缓冲
缓冲文件系统的特点是:在内存开辟一个“缓冲区”,为程序中的每一个文件使用;当执行读文件的操作时,从磁盘文件将数据先读入内存“缓冲区”,装满后再从内存“缓冲区”依此读出需要的数据。执行写文件的操作时,先将数据写入内存“缓冲区”,待内存“缓冲区”装满后再写入文件。
非缓冲文件系统依赖于操作系统,通过操作系统的功能对文件进行读写,是系统级的输入输出,它不设文件结构体指针,只能读写二进制文件,但效率高、速度快。
简单来说。缓冲文件系统需要缓冲区转换,非缓冲文件系统直接实现内核态和用户态的转换。当下内存都比较大,两种模式的运行速度快慢区别不大。
fopen头文件和函数
头文件:#include <stdio.h>
函数:FILE *fopen(const char *path, const char *mode);
fread和fwrite头文件和函数
头文件: #include <stdio.h>
函数: size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
函数: size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);
fseek和fseek头文件和函数
头文件: #include <stdio.h>
函数:int fseek(FILE *stream, long offset, int whence);
参数解释
void *ptr:指向被读取(写入)的元素数组指针
size_t size:要被读取(写入)的元素数组大小,以字节为单位
size_t nmemb:元素的个数,以size为单位
FILE *stream:指向FILE对象的指针
到此结束,师承上官可编程;


版权声明:本文为Jackice_Lee原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。