系统方面对文件的打开,读写,关闭

在这里插入图片描述

1. 系统方面打开文件的函数

open函数得到一个指定文件的文件描述符,如果出现错误则返回-1。open函数需要传入一个文件路径和操作模式,调用会返回一个整型的文件描述符。
在这里插入图片描述
在Linux系统中,open函数主要作用就是打开和创建文件,可以根据参数来定制需要的文件的属性和用户权限等各种参数。flag参数相当于是宏,并且是可选的,用于设置打开文件的模式。flag参数的取值如下:

O_RDONLY: 只读模式
O_WRONLY: 只写模式
O_RDWR : 读写模式
O_NONBLOCK: 非阻塞模式
O_APPEND: 追加模式
O_CREAT: 创建并打开一个新文件
O_TRUNC: 打开一个文件并截断它的长度为零(必须有写权限)
O_EXCL: 如果指定的文件存在,返回错误

#include <stdio.h>    
#include <errno.h>    
#include <string.h>    
#include <sys/types.h>    
#include <sys/stat.h>    
#include <fcntl.h>    

int main()    
{    
    int fd = open("log.txt", O_WRONLY);//只写入                                                                             
    printf("fd: %d, errror: %d, errstring: %s\n", fd, errno, strerror(errno));//打印文件描述符,错误码,错误信息    
    close(fd);    
                                                                         
    return 0;                                                                
}  

因为没有创建文件,没有log.txt文件,所以打开文件失败,文件描述符为-1。
在这里插入图片描述

然后将上面这句代码进行改动:int fd = open(“log.txt”, O_CREAT | O_WRONLY); 进行创建和写入。

在这里插入图片描述
可以看到文件描述符为3(open成功),但是log.txt这个文件的权限是乱的,可以用chmod 0XXX log.txt 进行修改,也可以用open修改。
在Linux系统中,umask是一个用于设置文件和目录默认权限的命令。每个文件和目录都有一组权限,包括读、写和执行权限。umask值是由三个八进制数字表示的。第一个数字表示所有者的权限,第二个数字表示组的权限,第三个数字表示其他人的权限。每个数字都可以是0到7之间的任何数字。所以在test.c文件中,可以将umask设为0,系统下的umask和用户设定的umask,程序用哪个采用就近原则。

#include <stdio.h>    
#include <errno.h>    
#include <string.h>    
#include <unistd.h>    
#include <sys/types.h>    
#include <sys/stat.h>    
#include <fcntl.h>    
    
int main()    
{    
	umask(0);
    int fd = open("log.txt",O_CREAT | O_WRONLY, 0666);                                                              
    printf("fd: %d, errror: %d, errstring: %s\n", fd, errno, strerror(errno));    
    close(fd);    
    
    return 0;    
}    

在这里插入图片描述

2. 系统方面对文件的写入

write函数是基于Linux系统中的一项函数调用,主要用于在打开/创建的文件中写入数据。 write()会把参数buf所指的内存写入count个字节到参数fd所指的文件内。 write函数包含的头文件为 #include <unistd.h>。
write()函数的三个参数分别为:文件描述符fd,缓冲区buf和写入字节数count。 当有错误发生时则返回-1,错误代码存入errno中。
在这里插入图片描述
要想在文件中写数据,write()函数需要3个参数,fd,count易得,还需要一个缓冲区buf,这个缓冲区里面有给文件中写入的数据,给缓冲区中写入数据,需用到snprintf()函数。
snprintf()是一个C语言标准库函数,它的三个参数分别为:缓冲区buf,缓冲区大小size和格式化字符串format。 如果格式化后的字符串长度超过了size,则会截断超出部分。用于格式化输出字符串,并将结果写入到指定的缓冲区。与sprintf()不同的是,snprintf()会限制输出的字符数,避免缓冲区溢出。
在这里插入图片描述

#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

int main()
{
    umask(0);
    int fd = open("log.txt",O_CREAT | O_WRONLY, 0666);
    printf("fd: %d, errror: %d, errstring: %s\n", fd, errno, strerror(errno));
    //写入
    const char *msg = "hello";
    int cnt = 3;
    while (cnt)
    {
        char buf[128];
        snprintf(buf, sizeof(buf), "%s, %d\n", msg, cnt);

        write(fd, buf, strlen(buf) + 1);
        --cnt;
    }
    close(fd);

    return 0;
}

这里有一个小细解,strlen求的是‘\0’之前字符串的长度,众所周知,c语言规定‘\0’用于判断字符串的结尾,而打印的时候需不需要带上‘\0’?上述代码是带上’\0’的,写入结果如下所示:
在这里插入图片描述
可以看到文件中有^@符号,这些是文件对‘\0’ 的处理,所以对文件进行写入字符串时,不需要带‘\0’,因为’\0’是c语言规定的,不是文件规定的。
当再次向文件中写入,会出现预料之外的结果(如下),这是因为上述代码open函数中的flag参数的原因,O_CREAT | O_WRONLY只是进行创建并打开一个新文件和只写模式,还需要O_TRUNC,如果是追加则需要O_APPEND。
在这里插入图片描述
flag参数的取值如下:

O_RDONLY: 只读模式
O_WRONLY: 只写模式
O_RDWR : 读写模式
O_NONBLOCK: 非阻塞模式
O_APPEND: 追加模式
O_CREAT: 创建并打开一个新文件
O_TRUNC: 打开一个文件并截断它的长度为零(必须有写权限)
O_EXCL: 如果指定的文件存在,返回错误

#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

int main()
{
    umask(0);
    int fd = open("log.txt",O_CREAT | O_WRONLY | O_TRUNC, 0666);
    printf("fd: %d, errror: %d, errstring: %s\n", fd, errno, strerror(errno));
    
    const char *msg = "hello";
    int cnt = 3;
    while (cnt)
    {
        char buf[128];
        snprintf(buf, sizeof(buf), "%s, %d\n", msg, cnt);

        write(fd, buf, strlen(buf));
        --cnt;
    }
    close(fd);

    return 0;
}

3. 系统方面对文件的读取

在这里插入图片描述

read()函数是基于Linux系统中的一项函数调用,主要用于从文件描述符fd所指的文件中读取count个字节到缓冲区buf中。 read()函数包含的头文件为 #include <unistd.h>。

read()函数的三个参数分别为:文件描述符fd,缓冲区buf和读取字节数count。 当有错误发生时则返回-1,错误代码存入errno中。

#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

int main()
{
    int fd = open("log.txt", O_RDONLY); //只读模式
    char buf[1024];
    size_t n = read(fd, buf, sizeof(buf) - 1);
    if (n > 0)
    {
        buf[n] = '\0';
        printf("%s\n",buf);
    }
	close(fd);
	
	return 0;

对于文件的读写,系统和c语言分别对‘\0’的处理是不一样的,所以在进行字符串到文件的写入或者是从文件中读取数据到c语言中,‘\0’就需要自己处理。如上,在读取字符串的时候,读取的字节数的大小减1,这个位置就准备用来放‘\0’。并且从文件中读取数据,不能进行按行读取,只能进行整体读取(或者是按字节数读取),而c语言按行读取时c语言内部进行了特殊处理。 读取结果如下:
在这里插入图片描述
所以c标准库里的fopen,fclose,fwrite,fread等函数都是将系统中的open,close,write,read等函数进行封装,fopen,fclose,fwrite,fread调用的就是系统中的open,close,write,read等函数。
open()函数是一个系统调用,返回的是文件句柄,文件的句柄是文件在文件描述副表里的索引。而fopen()是C的库函数,返回的是一个指向文件结构的指针。这两个函数的区别主要在于:

  1. open()函数可以打开任何类型的文件,而fopen()函数只能打开文本文件。
  2. open()函数返回一个文件描述符,而fopen()函数返回一个指向文件结构的指针。
  3. open()函数不需要stdio.h头文件,而fopen()函数需要stdio.h头文件。

close()函数和fclose()函数都是用于关闭文件的函数,它们之间的区别:

  1. close()函数是一个系统调用,而fclose()函数是C的库函数。
  2. close()函数需要一个文件描述符作为参数,而fclose()函数需要一个指向文件结构的指针作为参数。
  3. close()函数不会刷新缓冲区,而fclose()函数会刷新缓冲区。
  4. close()函数不会返回任何值,而fclose()函数会返回一个整数值。

4. 关闭文件close

在Linux中,close()函数是一个系统调用,用于关闭文件描述符,以便它不再引用任何文件并可以被重用。如果文件描述符是与记录锁定相关联的,则会删除这些锁定。如果文件描述符是与打开的文件相关联的,则会释放该文件所占用的资源。如果成功执行,则返回0,否则返回-1,并将失败原因记录在errno中。
在这里插入图片描述
close()函数的语法如下:


#include <unistd.h>

int close(int fd);

c语言对文件的打开和读写

  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ly@눈_눈

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值