【C语言】Linux 文件读写


前言

Linux 系统中,一切皆文件 在 Linux 中,扩展名对 Linux 内核并没有什么实际意义,但是可以用来人为区分不同的文件,方便用户使用。
  • 比如 .c 是C文件,.h是头文件一样,虽然在我们眼中有区别,但是在Linux中,他们都属于普通文件类型

今天我们来了解一下简单的文件I/O读写操作。


一、实现过程

1、创建hello.txt文件

  • ①、参数1:要打开的文件【可以用绝对路径】

  • ②、参数2:flags ,以下三个比较常用
    -—— O_RDWR:以读写的方式打开文件
    -—— O_CREAT:如果文件不存在,就创建该文件
    -—— O_TRUNC:若文件存在,则长度被截为0【可以理解为清空文件中的内容】

  • ③、参数3:0666【设置该文件的权限,0为8进制数的前导符号】
    大家在创建文件的时候会发现创建出来的文件,他的实际权限和我们设定的不太一样,这个我们待会再来聊。

  • open() 函数如果执行成功,会返回一个指向该文件的文件描述符 fd
    在运行最终代码的时候,会看到 fd = 3 ,是因为
    操作系统默认会打开 0、1、2 这三个文件描述符
    0:标准输入【默认是键盘】
    1:标准输出【默认是屏幕】
    2:标准出错【默认是屏幕】
    而新建的文件描述符 fd,是当前可用的文件描述符中最小的非负整数,所以这里的 fd 为 3

//创建hello.txt文件
if((fd = open("hello.txt", O_RDWR|O_CREAT|O_TRUNC, 0666)) < 0)
{
	printf("Open/Create file %s failure: %s\n", FILE_NAME, strerror(errno));
	return -1;
}
printf("Open/Create file %s fd[%d] successfully\n", FILE_NAME, fd);

2、写数据到hello.txt

  • ①、往文件描述符 fd 指向的文件中,写入MSG_STR这个字符串,内容是【Hello World\n】,写入的长度为 strlen(MSG_STR) 字节大小
  • ②、若执行写操作成功,write() 函数的返回值则是写入数据的字节大小
  • ③、若执行写操作失败,write() 函数的返回值则是一个 < 0 的数
//写数据到hello.txt中
if ((rv = write(fd, MSG_STR, strlen(MSG_STR))) < 0)
{
	printf("Write data to fd[%d] failure: %s\n", fd, strerror(errno));
	goto cleanup;
}
printf("Write %dB data to fd[%d]: %s\n", rv, fd, MSG_STR);

3、从hello.txt中读数据

  • ①、把 “ 文件描述符 fd 指向的文件 ” 中的内容读数据到 buf 中,读数据的长度为 sizeof(buf) 字节大小
  • ②、若执行读操作成功,read() 函数的返回值则是读出的数据的字节大小
  • ③、若执行读操作失败,read() 函数的返回值则是一个 <0 的数
//从hello.txt中读数据
lseek(fd, 0, SEEK_SET);
if ((rv = read(fd, buf, sizeof(buf))) < 0)
{
	printf("Read data from fd[%d] failure: %s\n", fd, strerror(errno));
	goto cleanup;
}
printf("Read %luB data from fd[%d]: %s\n", strlen(buf), fd, buf);

二、具体代码

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

#define FILE_NAME 	"hello.txt"
#define BUF_LEN		1024
#define MSG_STR		"Hello World\n"

int main(int argc, char **argv)
{
	int 	fd = -1;
	int 	rv = -1;
	char 	buf[BUF_LEN];
	memset(buf, 0, sizeof(buf));
	
	//创建hello.txt文件
	if ((fd = open(FILE_NAME, O_RDWR|O_CREAT|O_TRUNC, 0666)) < 0)
	{
		printf("Open/Create file %s failure: %s\n", FILE_NAME, strerror(errno));
		return -1;
	}
	printf("Open/Create file %s fd[%d] successfully\n", FILE_NAME, fd);
	
	//写数据到hello.txt中
	if ((rv = write(fd, MSG_STR, strlen(MSG_STR))) < 0)
	{
		printf("Write data to fd[%d] failure: %s\n", fd, strerror(errno));
		goto cleanup;
	}
	printf("Write %dB data to fd[%d]: %s\n", rv, fd, MSG_STR);
	
	//从hello.txt中读数据
	lseek(fd, 0, SEEK_SET);
	if ((rv = read(fd, buf, sizeof(buf))) < 0)
	{
		printf("Read data from fd[%d] failure: %s\n", fd, strerror(errno));
		goto cleanup;
	}
	printf("Read %luB data from fd[%d]: %s\n", strlen(buf), fd, buf);
	
cleanup:
	close(fd);

	return 0;
}

三、运行效果

在这里插入图片描述
好了,我们接着来聊新建的 hello.txt 文件的权限问题,为什么我在代码里设置的访问权限是0666(rw-rw-rw-),但是实际上创建的文件的权限却是0664(rw-rw-r–)呢?
这其实是权限掩码在搞鬼,我们使用命令

umask

在这里插入图片描述

就可以查看权限掩码了,可以看到我这的权限掩码是0002,那什么是权限掩码呢
大家都知道我们的权限码其实是3个8进制的数字组成的,如0777、0666。
权限掩码就是相当于把相应的权限给屏蔽掉了,我这里就是把其他组的用户的写权限给屏蔽掉了。
我们将 预设的访问权限 减去 权限掩码,得到的就是实际上创建文件时的访问权限。
0666 - 0002 = 0664 (get√)


总结

以上是对Linux文件读写的一些理解,如有写的不好的地方,还请各位大佬不吝赐教

  • 4
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Simply myself

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

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

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

打赏作者

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

抵扣说明:

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

余额充值