当前位置:网站首页>C语言的文件操作(一)
C语言的文件操作(一)
2022-07-31 05:09:00 【怎么这么多名字都被占了】
好久没发文章了,这次就讲讲C语言的文件操作吧。
C语言的文件操作主要有两种方式,一种是通过open(2)和close(2)进行的,还有一种是通过fopen(3)和fclose(3)进行的。今天我们就来讲讲用open(2)和close(2)的文件操作,虽然这个用法不常用
目录
open(2)里面的2是什么意思?
有些人可能就迷糊了,open(2)里面的2是什么意思?
这里面的2是在man指令查看帮助时在"open"之前输入的,即
man 2 open
我之前说过,man指令可以查看帮助,当我们输入man man时,就可以看到man的使用方法,我们不妨从这里找到答案
首先我们可以看到这句话
man - format and display the on-line manual pages
意思是说:man命令可以格式化和显示在线帮助页面
在简介一栏里,我们可以看到man的参数
man [-acdfFhkKtwW] [--path] [-m system] [-p string] [-C con-
fig_file] [-M pathlist] [-P pager] [-B browser] [-H htmlpager]
[-S section_list] [section] name ...
在描述一栏里,我们可以看到man的粗略使用方法
man formats and displays the on-line manual pages.
If you specify section, man only looks in that section of the manual.
name is normally the name of the manual page, which is typically the name of a command, function, or file.
However, if name contains a slash (/) then man interprets it as a file specification, so that you can do man ./foo.5 or even man /cd/foo/bar.1.gz.
意思是:man格式化并显示在线手册页面。如果您指定section参数,man只查看手册的该章节。name参数通常是手册页面的名称,通常是命令、函数或文件的名称。然而,如果名称包含斜杠(/),则man将其解释为文件规范,以便您可以执行man /foo.5甚至是man /cd/foo/bar.1.gz。
综上,我们可以知道,“2”是section参数,“open”是name参数
那么,section参数怎么用呢?
section参数中,我最常使用的是1(系统命令)、2(系统函数)、3(库函数)
open(2)函数属于系统函数,而fopen(3)属于库函数
扯了这么多,还没讲文件读写呢
文件写入
示例代码
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
int main(void){
// 创建文件
// 文件名:test
// 读取方式:只写。如果没有文件就新建一个
// 权限:有且只有用户读写权限
int des = open("test", O_WRONLY|O_CREAT, S_IRUSR|S_IWUSR);
// 判断异常
if(des == -1){
perror("open");
return -1;
}
char data[] = "Hello World"; // 定义字符串
// 写入数据
int err = write(des, data, (strlen(data) + 1));
if(err == -1){
perror("write");
return -1;
}
// 关闭文件
err = close(des);
if(err == -1){
perror("close");
return -1;
}
return 0;
}
接下来我们来解释一下这段代码
由于我英语水平有限,man文档的有些地方看不懂,讲的有误的望指正
open(2)函数
首先我们来看open(2)函数的原形
int open(const char *pathname, int flags);
int open(const char *pathname, int flags, mode_t mode);
没错,open(2)函数有两个原形,难道C语言也可以函数重载了吗?
其实,这并不是真正的函数重载。我们可以通过好几种方法实现假的函数重载,主要原理是使用可变参数个数
这里面主要有3个参数,我们全部使用了
第一个参数pathname,是文件名
第二个参数flags,规定了读写方式。必须包括O_RDONLY(只读)或O_WRONLY(只写)或O_RDWR(读或写)。这个参数比较奇怪,可以通过"|"相连。系统函数真是高深啊!
这个参数我写的是 O_WRONLY|O_CREAT ,O_CREAT表示如果没有文件就创建一个新的
第三个参数mode,规定了权限。文件权限有:
当前用户权限、当前用户组权限、其他用户的权限。每个权限又有读(r)、写(w)、执行(x),我们可以通过ls -l 查看权限
-rw-------
这表示当前用户可读写
这个参数可以有
S_IRWXU 当前用户可读、可写、可执行
S_IRUSR 当前用户可读
S_IWUSR 当前用户可写
S_IXUSR 当前用户可执行
S_IRWXG 当前用户组可读、可写、可执行
S_IRGRP 当前用户组可读
S_IWGRP 当前用户组可写
S_IXGRP 当前用户组可执行
S_IRWXO 其他用户可读、可写、可执行
S_IROTH 其他用户可读
S_IWOTH 其他用户可写
S_IXOTH 其他用户可执行
同样,这个参数也可以用"|"连接
注意,如果文件已存在,mode参数不会有作用,而且,mode参数必须和O_CREAT一起用。
讲完参数,该将返回值了。如果成功,这个返回值是一个描述符(descriptor),也就是一个供系统调用的非负整数。并且,函数运行时会产生一个描述(description),也就是一个打开的文件的条目,存储在系统范围表(system-wide table)中。
write(2)函数
先看原形
ssize_t write(int fd, const void *buf, size_t count);
第一个参数fd,是描述符(descriptor)
第二个参数buf,是一个指针类型的变量,从这个指针存(指向)的地址开始,取第三个参数count长度
如果函数返回-1,就说明出错了。否则程序返回写入的长度
close(2)函数
先看原形
int close(int fd);
参数fd就是描述符(descriptor)
如果成功,返回0,否则返回-1
perror(3)函数
这个函数我就简单讲讲
perror(3)函数接收一个参数,是函数名,它会输出这个函数报的错。前提是这个函数得先出错,而且在man文档里提到了出错会改变errno的值
读取文件
示例代码
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
int main(void){
// 创建文件
// 文件名:test
// 读取方式:只读
int des = open("test", O_RDONLY);
// 判断异常
if(des == -1){
perror("open");
return -1;
}
char data[12]; // 定义字符串
// 读取数据
int err = read(des, data, 12);
if(err == -1){
perror("read");
return -1;
}
printf("%s\n", data);
// 关闭文件
err = close(des);
if(err == -1){
perror("close");
return -1;
}
return 0;
}
read(2)函数
这个函数的原形是这样的
ssize_t read(int fd, void *buf, size_t count);
跟write(2)很向,只不过是从fd这个描述符(descriptor)读取count长度的数据,并存入buf指定(指向)的地址里。当然,这个地址要流出足够的空间。可以采用malloc(3)动态分配,或者直接采用数组。
总结
这个操作总体来看比较繁琐,但这确是Linux文件的最基础操作,也是网络编程的重要一环。Windows也是可以使用的
边栏推荐
- Kubernetes加入集群的TOKEN值过期
- CentOS7 install MySQL graphic detailed tutorial
- Redis Advanced - Cache Issues: Consistency, Penetration, Penetration, Avalanche, Pollution, etc.
- numpy和pytorch中的元素拼接操作:stack,concatenat,cat
- MySQL (updating)
- mysql5.7.35安装配置教程【超级详细安装教程】
- SQL statement to range query time field
- mysql uses on duplicate key update to update data in batches
- Typec手机有线网卡网线转网口转接口快充方案
- Apache DButils使用注意事项--with modifiers “public“
猜你喜欢
SQL行列转换
<urlopen error [Errno 11001] getaddrinfo failed>的解决、isinstance()函数初略介绍
面试官问我TCP三次握手和四次挥手,我真的是
[mysql improves query efficiency] Mysql database query is slow to solve the problem
centos7安装mysql5.7
Goodbye to the cumbersome Excel, mastering data analysis and processing technology depends on it
城市内涝及桥洞隧道积水在线监测系统
The interviewer asked me TCP three handshake and four wave, I really
Minesweeper game (written in c language)
Distributed Transactions - Introduction to Distributed Transactions, Distributed Transaction Framework Seata (AT Mode, Tcc Mode, Tcc Vs AT), Distributed Transactions - MQ
随机推荐
[mysql improves query efficiency] Mysql database query is slow to solve the problem
Reference code series_1. Hello World in various languages
ES source code API call link source code analysis
Sql解析转换之JSqlParse完整介绍
关于小白安装nodejs遇到的问题(npm WARN config global `--global`, `--local` are deprecated. Use `--location=glob)
MYSQL下载及安装完整教程
太厉害了,终于有人能把文件上传漏洞讲的明明白白了
再见了繁琐的Excel,掌握数据分析处理技术就靠它了
torch.normal函数用法
mysql uses on duplicate key update to update data in batches
MySQL忘记密码怎么办
Centos7 install mysql5.7 steps (graphical version)
工作流编排引擎-Temporal
wx.miniProgram.navigateTo在web-view中跳回小程序并传参
Interview Redis High Reliability | Master-Slave Mode, Sentinel Mode, Cluster Cluster Mode
12 reasons for MySQL slow query
Moment Pool Cloud quickly installs packages such as torch-sparse and torch-geometric
Tapdata 与 Apache Doris 完成兼容性互认证,共建新一代数据架构
分布式事务处理方案大 PK!
Shell重油常压塔模拟仿真与控制