open函数和close函数的使用

学习几个常用的Linux系统I/O函数:open、close、write、read和lseek。注意,系统调用函数必须都考虑返回值。

(1open函数的使用

首先,需要包含三个头文件:<sys/types.h>   <sys/stat.h>   <fcntl.h>

以如下代码为例:

[root@localhost src]# ls

add.c  div.c  hello  main.c  mul.c  sub.c  zsx  zsx.c

[root@localhost src]# vim zsx.c

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>  //前三个头文件对应库函数open
#include <stdlib.h>  //对应库函数exit
#include <stdio.h>   //对应库函数 perror和printf
#include <unistd.h>  //对应库函数closeint main( )
{int fd;  //记录open函数返回值fd = open("zsxhello",O_RDWR);  //以读写方式打开一个不存在的文件,当前目录printf("fd=%d\n",fd);if( fd == -1 )  //如果打开失败{perror("open zsxhello");  //则输出打开失败的原因(详细错误信息)exit(1);  //并结束当前进程,则后面程序不再执行}//如果打开成功,继续向后执行  注意exit函数结束当前进程,在头文件stdlib.h中声明int ret = close( fd );    //打开后关闭该文件printf("ret=%d\n",ret);if( ret == -1 )     //如果关闭文件失败{perror("close zsxhello");   //输出出错的详细信息exit(1);}return 0;
}

[root@localhost src]# gcc -pipe -pedantic -Wall -ggdb3 zsx.c -o zsx

[root@localhost src]# ldd zsx

       linux-vdso.so.1 =>  (0x00007fff21f18000)

       libc.so.6 => /lib64/libc.so.6 (0x00007eff28730000)

       /lib64/ld-linux-x86-64.so.2 (0x00007eff28b10000)

[root@localhost src]# ./zsx

fd=-1  //文件打开失败

open zsxhello: No such file or directory   //错误详细信息

 

//下面说明如何利用open函数创建一个文件

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>int main( )
{int fd;fd = open("hello",O_RDWR);  //打开一个已有的文件printf("fd=%d\n",fd);if( fd == -1 ){perror("open hello");}int fd1 = open("zsxhello",O_RDWR | O_CREAT,0777);  //创建一个zsxhello文件printf("fd1=%d\n",fd1);if( fd1 == -1 ){perror("open zsxhello");}int ret = close( fd ); //关闭hello文件printf("ret=%d\n",ret);if( ret == -1 ){perror("close hello");}int ret1 = close( fd1 );  //关闭zsxhello文件printf("ret1=%d\n",ret1);if( ret1 == -1 ){perror("close zsxhello");}return 0;
}

[root@localhost src]# ./zsx

fd=3  

fd1=4   //可以看到新打开的两个文件描述符为3、4

ret=0 

ret1=0   //成功关闭文件

 

int fd1 = open("zsxhello",O_RDWR | O_CREAT,0777);  //创建一个zsxhello文件

O_RDWR | O_CREAT  参数表示创建该文件,且以读写的方式打开   0777定义创建文件的权限,文件的权限都是8进制数(以0开头的数),0777等价于777。

[root@localhost src]# ls

add.c  div.c  hello  main.c  mul.c  sub.c  zsx  zsx.c  zsxhello

[root@localhost src]# ll zsxhello

-r-xr-xr-x. 1 root root 0 Mar 18 18:09 zsxhello

[root@localhost src]# umask  //掩码,操作系统对文件的一种保护机制

0777

注意:可看到文件zsxhello的权限并不是0777,而是0555这是因为文件的实际权限与掩码umask有关。因此,可以根据掩码值,来计算出相应的给定值,从而达到自己想要的最终实际值,也可以修改掩码: umask 0000  将掩码值修改为 0000

文件权限由open的mode参数和当前进程的umask掩码共同决定:

//利用open函数对文件进行截断  O_TRUNC参数

将文件截断就是将文件内容删除一部分,留一部分。将文件截断为0就是删除文件全部内容(清空)。代码如下:

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>int main( )
{int fd;fd = open("hello",O_RDWR | O_TRUNC); //以读写方式打开hello文件,并将其截断为0printf("fd=%d\n",fd);if( fd == -1 ){perror("open hello");exit(1);     //若打开失败,退出当前进程,此时main函数返回值不再为0}int ret;ret = close( fd );printf("ret=%d\n",ret);if( ret == -1 ){perror("close hello");exit(1);  //若关闭失败,退出当前进程,此时main函数返回值不再为0}return 0;
}

[root@localhost src]# ll hello

-rwxrwxrwx. 1 root root 14 Mar 18 16:58 hello

[root@localhost src]# ./zsx

fd=3

ret=0

[root@localhost src]# ll hello

-rwxrwxrwx. 1 root root 0 Mar 18 18:38 hello

注意上面代码:对于Linux系统I/O函数,都有返回值,且需要对返回值进行判断,并作出相应处理,如退出当前进程。

//利用open函数判断文件是否存在  O_CREATO_EXCL参数必须同时使用,即通过创建文件的方式来判断其是否存在,如果存在,出错,并给出提示。代码如下:

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>int main( )
{int fd;fd = open("hello",O_RDWR | O_CREAT | O_EXCL,0777);  判断hello文件是否存在 printf("fd=%d\n",fd);if( fd == -1 ){perror("open hello");exit(1);}int ret;ret = close( fd );printf("ret=%d\n",ret);if( ret == -1 ){perror("close hello");exit(1);}return 0;
}

[root@localhost src]# ./zsx

fd=-1

open hello: File exists

如果将fd = open("hello",O_RDWR | O_CREAT | O_EXCL,0777);    改为:  fd = open("hello",O_RDWR | O_CREAT,0777);  仍然能正常打开已经存在的文件,对于不存在的文件则创建,执行结果:

[root@localhost src]# ./zsx

fd=3

ret=0

(2close函数的使用

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

int close(int fd);    //返回值为0或-1,0代表关闭文件成功,-1代表关闭文件失败。 参数为所要关闭文件的文件描述符。 关闭文件出错,则会赋值给errno一个对应的代码值。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/385408.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

1091. Acute Stroke (30)

One important factor to identify acute stroke (急性脑卒中) is the volume of the stroke core. Given the results of image analysis in which the core regions are identified in each MRI slice, your job is to calculate the volume of the stroke core. Input Speci…

stat函数(stat、fstat、lstat)

#include <sys/types.h> #include <sys/stat.h> #include <unistd.h> //需包含头文件 有如下三个函数的函数原型&#xff1a; int stat(const char *path, struct stat *buf); 第一个形参&#xff1a;指出文件&#xff08;文件路径&#xff09;&…

【Leetcode | 235】 235. 二叉搜索树的最近公共祖先

给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先。 百度百科中最近公共祖先的定义为&#xff1a;“对于有根树 T 的两个结点 p、q&#xff0c;最近公共祖先表示为一个结点 x&#xff0c;满足 x 是 p、q 的祖先且 x 的深度尽可能大&#xff08;一个节点也可以是它自己…

CPU和MMU(内存管理单元)

CPU的架构&#xff1a;要求能够理解从源程序到微指令的整个经历过程&#xff1a;存储器的层次结构&#xff08;网络资源下载到硬盘、磁盘缓存、内存、Cache、寄存器&#xff09;&#xff1b;CPU的四大部分&#xff1a;ALU、CU、中断系统和寄存器&#xff1b;程序执行的整个过程…

【C++ Primer | 09】容器适配器

一、stack s.push(): 向栈内压入一个成员&#xff1b; s.pop(): 从栈顶弹出一个成员&#xff1b; s.empty(): 如果栈为空返回true&#xff0c;否则返回false&#xff1b; s.top(): 返回栈顶&#xff0c;但不删除成员&#xff1b; s.size(): 返回栈内元素…

进程控制块PCB(进程描述符)

&#xff08;1&#xff09;PCB 每个进程在内核中都有一个进程控制块&#xff08;PCB&#xff09;来维护进程相关的信息&#xff0c;Linux内核的进程控制块是task_struct结构体。grep -r “task_struct” / 可以查找根目录下&#xff0c;包含task_struct的文件文件。或者 find…

【C++ Primer | 19】控制内存分配

1. 测试代码&#xff1a; #include <iostream> #include <new> #include <cstring> #include <cstdlib> using namespace std;void* operator new(size_t size) {cout << "global Override operator new" << endl;if (void* p…

【第15章】虚函数

一、为什么基类中的析构函数要声明为虚析构函数&#xff1f; 直接的讲&#xff0c;C中基类采用virtual虚析构函数是为了防止内存泄漏。具体地说&#xff0c;如果派生类中申请了内存空间&#xff0c;并在其析构函数中对这些内存空间进行释放。假设基类中采用的是非虚析构函数&am…

【C++ Primer | 08】IO库

一、istringstream类 描述&#xff1a;从流中提取数据&#xff0c;支持 >> 操作 这里字符串可以包括多个单词&#xff0c;单词之间使用空格分开 #include <iostream> #include <sstream> using namespace std; int main() {istringstream istr(&quo…

EXEC函数族的一般规律

事实上&#xff0c;只有execve是真正的系统调用&#xff0c;其它五个函数最终都调用execve&#xff0c;所以execve在man手册第2节&#xff0c;其它函数在man手册第3节。这些函数之间的关系如下图所示。

进程间通信的方法

Linux环境下&#xff0c;进程地址空间相互独立&#xff0c;每个进程各自有不同的用户地址空间。任何一个进程的全局变量在另一个进程中都看不到&#xff0c;所以进程和进程之间不能相互访问&#xff0c;要交换数据必须通过内核&#xff0c;在内核中开辟一块缓冲区&#xff0c;进…

pipe函数

#include <unistd.h> int pipe(int pipefd[2]); 作用&#xff1a;创建管道 成功&#xff1a;0&#xff1b;失败&#xff1a;-1&#xff0c;设置errno 函数调用成功返回r/w两个文件描述符。无需open&#xff0c;但需手动close。规定&#xff1a;fd[0] …

mmap内存映射、system V共享内存和Posix共享内存

linux内核支持多种共享内存方式&#xff0c;如mmap内存映射&#xff0c;Posix共享内存&#xff0c;以system V共享内存。当内核空间和用户空间存在大量数据交互时&#xff0c;共享内存映射就成了这种情况下的不二选择。它能够最大限度的降低内核空间和用户空间之间的数据拷贝&a…

匿名映射

通过使用我们发现&#xff0c;使用映射区来完成文件读写操作十分方便&#xff0c;父子进程间通信也较容易。但缺陷是&#xff0c;每次创建映射区一定要依赖一个文件才能实现。通常为了建立映射区要open一个temp文件&#xff0c;创建好了再unlink、close掉&#xff0c;比较麻烦。…

信号的产生和状态

信号的产生&#xff1a;1.按键产生&#xff0c;如&#xff1a;Ctrlc&#xff08;内核向进程发送信号&#xff0c;杀死该进程&#xff09;、Ctrlz、Ctrl\&#xff1b;2.系统调用产生&#xff0c;如&#xff1a;kill、raise、abort&#xff1b;3.软件条件产生&#xff0c;如&…

【C++ Priemr | 15】虚函数常见问题

1. 在成员函数中调用虚函数&#xff1a; #include <iostream> using namespace std; class CBase { public:void func1(){func2();}virtual void func2() { cout << "CBase::func2()" << endl; } }; class CDerived : public CBase { public:virt…

965. 单值二叉树

如果二叉树每个节点都具有相同的值&#xff0c;那么该二叉树就是单值二叉树。 只有给定的树是单值二叉树时&#xff0c;才返回 true&#xff1b;否则返回 false。 示例 1&#xff1a; 输入&#xff1a;[1,1,1,1,1,null,1] 输出&#xff1a;true示例 2&#xff1a; 输入&#…

958. 二叉树的完全性检验

给定一个二叉树&#xff0c;确定它是否是一个完全二叉树。 百度百科中对完全二叉树的定义如下&#xff1a; 若设二叉树的深度为 h&#xff0c;除第 h 层外&#xff0c;其它各层 (1&#xff5e;h-1) 的结点数都达到最大个数&#xff0c;第 h 层所有的结点都连续集中在最左边&a…

信号捕捉(signal、sigaction)

信号的基本属性&#xff1a;软中断&#xff0c;由内核发送&#xff0c;内核处理。某个进程通过内核向另一个进程发送信号时&#xff08;引起信号产生的五个因素&#xff09;&#xff0c;另一个进程将会陷入内核进行中断处理&#xff0c;未决信号集中相应信号置1&#xff0c;当递…

可/不可重入函数

一个函数在被调用执行期间&#xff08;尚未调用结束&#xff09;&#xff0c;由于某种时序&#xff08;递归或者处理信号捕捉时等情况&#xff09;又被重复调用&#xff0c;称之为“重入”。根据函数实现的方法可分为“可重入函数”和“不可重入函数”两种。看如下程序。 可以看…