Linux C/C++编程: 文件操作open/close、fopen与freopen/fclose

article/2025/9/14 1:21:54

open是linux下的底层系统调用函数,fopen与freopen c/c++下的标准I/O库函数,带输入/输出缓冲。

linxu下的fopen是open的封装函数,fopen最终还是要调用底层的系统调用open。
所以在linux下如果需要对设备进行明确的控制,那最好使用底层系统调用(open)

  • open对应的文件操作有:close, read, write,ioctl 等。
  • fopen 对应的文件操作有:fclose, fread, fwrite, freopen, fseek, ftell, rewind等。
  • freopen用于重定向输入输出流的函数,该函数可以在不改变代码原貌的情况下改变输入输出环境,但使用时应当保证流是可靠的

open和fopen的区别:

  • fread是带缓冲的,read不带缓冲.
  • fopen是标准c里定义的,open是POSIX中定义的.
  • fread可以读一个结构.read在linux/unix中读二进制与普通文件没有区别.
  • fopen不能指定要创建文件的权限.open可以指定权限.
  • fopen返回文件指针,open返回文件描述符(整数).
  • linux/unix中任何设备都是文件,都可以用open,read.

1、open、close系统调用(linux)

理论

#include <sys/types.h> 
#include <sys/stat.h> 
#include <fcntl.h> 	
/*
* 返回:若成功则为新文件描述符,若出错为-1
*/
int open( const char * pathname, int oflags);			
int open(char *filename, int flags, mode_t mode); #include <unistd.h> 
/*
* 返回:若成功则为 o, 若出错则为 -1(关闭一个已关闭的描述符会出错)
*/
int close(int fd);

1、功能:open 函数将 filename 转换为一个文件描述符,并且返回描述符数字。返回的描述符总是在进程中当前没有打开的最小描述符

2、参数:
pathname 是待打开/创建文件的路径名
flags 参数指明了进程打算如何访问这个文件:

• O_RDONLY: 只读
• O_WRONLY: 只写。
• O_RDWR: 可读可 写。

以上三者是互斥的,即不可以同时使用。至少得使用上述三个常量中的一个

以读的方式打开一个已存在的文件:fd = open("foo.txt", O_RDONLY, 0);

flags 参数也可以上面的一个 | 下面的零个或者多个:
• O_CREAT: 如果文件不存 ,就创建它的一个截断的 (truncated) (空)文件
• O_TRUNC: 如果文件巳经 在,就截断它
• O_APPEND: 在每次 操作前,设置文件位置到文件的结尾处

打开一个已存在文件,并在后面添加一些数据:
fd = open("foo .txt", O_ ONLYIO_APPEND, 0);

mode 参数仅当创建新文件时才使用(而且必须用),用于指定文件的访问权限。
在这里插入图片描述
作为上下文的一部分,每个进程都会有一个umask、它是通过调用unmask函数来设置的。

当进程通过带某个 mode 参数的 open 函数调用来创建一个新文件时,文件的访问权
限位被设置为 mode & ~ umask

2、返回值:

成功则返回文件描述符,否则返回 -1。 返回文件描述符(整型变量0~255)。由open 返回的文件描述符一定是该进程尚未使用的最小描述符。只要有一个权限被禁止则返回-1。

错误代码:

  • EEXIST 参数pathname 所指的文件已存在,却使用了O_CREAT和O_EXCL旗标。

  • EACCESS 参数pathname所指的文件不符合所要求测试的权限。

  • EROFS 欲测试写入权限的文件存在于只读文件系统内。

  • EFAULT 参数pathname指针超出可存取内存空间。

  • EINVAL 参数mode 不正确。

  • ENAMETOOLONG 参数pathname太长。

  • ENOTDIR 参数pathname不是目录。

  • ENOMEM 核心内存不足。

  • ELOOP 参数pathname有过多符号连接问题。

  • EIO I/O 存取错误。

实践

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
int main ()
{int fd1, fd2;fd1 = open("a.txt", O_RDONLY, 0);printf("fd1 = %d\n", fd1);close(fd1);fd2 = open("b.txt", O_RDONLY, 0);printf("fd2 = %d\n", fd2);close(fd2);return(0);
}

现象: 如果文件不存在,返回-1。
如果文件存在,返回3
在这里插入图片描述

分析: Linux shell创建的每个进程开始时都有三个打开的文件:标准输入(描述符为 0) 、标准输出(描述符为 1) 和标准错误(描述符为 2), open返回的描述符总是在进程中当前没有打开的最小描述符。

fopen、freopen、fclose库函数

理论

#include<stdio.h>
/*
* 作用: 使用给定的模式 mode 打开 filename 所指向的文件
* 参数:
* 	filename -- 这是 C 字符串,包含了要打开的文件名称。
*   mode -- 这是 C 字符串,包含了文件访问模式
* 返回值: 该函数返回一个 FILE 指针。否则返回 NULL,且设置全局变量 errno 来标识错误。
*/
FILE *fopen(const char *filename, const char *mode)/*
* 作用:把一个新的文件名 filename 与给定的打开的流 stream 关联,同时关闭流中的旧文件。
* 参数:
* 	filename -- 这是 C 字符串,包含了要打开的文件名称。
*   mode -- 这是 C 字符串,包含了文件访问模式
*   stream -- 这是指向 FILE 对象的指针(文件指针),该 FILE 对象标识了要被重新打开的流。通常使用标准流文件(stdin/stdout/stderr)
* 返回值: 如果成功则返回该指向该stream的指针,否则为NULL。
*/
FILE *freopen(const char *filename, const char *mode, FILE *stream)/*
* 作用:  关闭流 stream。刷新所有的缓冲区。
* 参数:  stream -- 这是指向 FILE 对象的指针,该 FILE 对象指定了要被关闭的流。
* 返回值: 如果流成功关闭,则该方法返回零。如果失败,则返回 EOF
*/
int fclose(FILE *stream)

mode取值
在这里插入图片描述

  • “r"或"rb” 以只读方式打开文件,该文件必须存在。
  • “w"或"wb” 以写方式打开文件,并把文件长度截短为零。
  • “a"或"ab” 以写方式打开文件,新内容追加在文件尾。
  • "r+"或"rb+“或"r+b” 以更新方式打开(读和写)
  • "w+"或"wb+“或"w+b” 以更新方式打开,并把文件长度截短为零。
  • "a+"或"ab+“或"a+b” 以更新方式打开,新内容追加在文件尾。

字母b表示文件时一个二进制文件而不是文本文件。(linux下不区分二进制文件和文本文件)

实践

freopen使用

#include <stdio.h>
#include <string.h>int main ()
{FILE *fp;printf("该文本重定向到 stdout \n");fp = freopen("file.txt", "w+", stdout); // 关联标准输出 STDOUT 到文件 file.txtprintf("该文本重定向到 file.txt dddddddddddddd\n");fclose(fp);return(0);
}

在这里插入图片描述

fclose封装

void Fclose(FILE *fp)
{if (fclose(fp) != 0){printf("fclose error");exit(0);}
}

http://chatgpt.dhexx.cn/article/aMC1suSY.shtml

相关文章

Linux之open()、close()函数

目录 open函数 函数介绍 头文件及函数原型 参数 close函数 函数介绍 头文件函数原型 open()、close()函数使用 open函数 函数介绍 在Linux中open()函数用来打开或创建一个文件&#xff0c;当打开文件失败时返回值为-1&#xff1b;成功则返回作为文件描述符(一个非负的…

Linux李哥私房菜——open、close和fd

open() 头文件&#xff1a;#include<fcntl.h>//在centos6.0中只要此头文件就可以#include<sys/types.h>#incldue<sys/stat.h> 功能&#xff1a;打开和创建文件&#xff08;建立一个文件描述符&#xff0c;其他的函数可以通过文件描述符对指定文件进行读取与…

详解C中的系统调用open/close/read/write

文章目录 open() and close()read() and write()实操:代码示例1 将in.txt文件中的内容写入到out.txt文件中&#xff08;一个一个字符写入&#xff09;2 将in.txt文件中的内容写入到out.txt文件中&#xff08;数组写入&#xff09; 先谈谈open/close/read/write与fopen/fclose/f…

JavaScript中window对象及open和close使用

Window对象 是一个顶级对象&#xff0c;不是任何对象的属性&#xff0c;所以可以不写window.xxx而直接使用内部的属性和方法。 实际上&#xff0c;在web前端开发时&#xff0c;所有的全局变量都自动成为window对象的属性 Window对象的属性 Screen History Location Navigat…

Python基础(十三)——文件操作(open函数、close函数)

本文以Python3以上为学习基础。 目录 1、 使用文件操作第一原则 2、open函数 2.1、文件打开模式 2.1.1、只读模式打开文件——只读&#xff08;r&#xff09; 2.1.2、读写模式打开文件——读写模式&#xff08;r&#xff09; ​ 2.1.3、写模式打开文件——写模式&#…

layer中的open与close

关于layer中的open方法与close方法 open方法open函数的定义open函数里面optionsopen函数中返回的值 close方法如何使用close方法关于layer中的一些发现 写在最后的话 open方法 open函数用来创建一个弹出层。 open函数的定义 形式为&#xff1a;layer.open(options) 例如&…

open函数详解与close函数详解

open() 头文件&#xff1a;#include<fcntl.h>//在centos6.0中只要此头文件就可以#include<sys/types.h>#incldue<sys/stat.h> 功能&#xff1a;打开和创建文件&#xff08;建立一个文件描述符&#xff0c;其他的函数可以通过文件描述符对指定文件进行读取与…

open和close函数

open函数&#xff1a;打开或创建文件 系统调用open可以用来打开普通文件、块设备文件、字符设备文件、链接文件和管道文件&#xff0c;但只能用来创建普通文件&#xff0c;创建特殊文件需要使用特定的函数。 头文件&#xff1a; #include <sys/types.h> #include <…

linux close 头文件,Linux open close read write lseek函数的使用

我们经常需要在Linux中进行文件操作,今天我就来分享下文件操作用到的一些函数 1 open 所需头文件: 函数原型:int open(const char *pathname,flags,int perms) pathname:被打开的文件名,可包含路径 flag :文件打开的方式,参数可以通过“|” 组合构成,但前3 个参数不能互…

linux的open close函数

目录 opencloseopen 参数说明代码 解析报错不用怕,我提供解决思路 前言 开始进入学linux的第一个阶段 第一阶段的 Linux的系统函数 第一节 先讲 open close 函数 open 怎么在liunx查看呢 我们利用下面的命令 linux自带的工具 man 手册 man 1 是普通shell 的命令 比如 ls ma…

简述Java序列化的几种方式

目录 JDK原生的序列化 字符串获取字节流 Protobuf Protostuff Thrift kryo hessian fst JSON字符串序列化 Jackson Gson FastJson 序列化和反序列化在网络传输过程中需要做的事情。 序列化 就是得的 字节流&#xff0c;反序列化就是得的对象。 下面梳理Java编程需要…

java序列化之writeObject 和readObject

什么是序列化和反序列化&#xff1f; 序列化&#xff1a;将对象转化为字节的过程称为序列化过程。 反序列化&#xff1a;将字节转化为对象的过程称为反序列化。 序列化主要应用于网络传输和数据存储的场景。在java中&#xff0c;只有类实现了java.io.serializable接口&#x…

java序列化总结

目录 对象序列化是什么 为什么需要序列化与反序列化 序列化及反序列化相关知识 Java 序列化中如果有些字段不想进行序列化&#xff0c;怎么办&#xff1f; Java序列化接口 java.io.Serializable 使用序列化和serialVersionUID进行类重构 Java外部化接口 java.io.Externa…

java序列化接口Serializable

Serializable接口说明 类的可序列化性通过实现(implements) java.io.Serializable可序列化接口。 没有实现这个接口的类不会将其任何状态序列化或反序列化。 可序列化类的所有子类型本身可序列化。 序列化接口没有方法或字段只用于识别可序列化的语义。 为了允许序列化不可序…

Java序列化之serialVersionUID

Java序列化之serialVersionUID 今天讲一讲Java对象中的serialVersionUID&#xff0c;先从序列化讲起。 什么是序列化 序列化&#xff0c;简单的说&#xff0c;就是将一个对象转化&#xff08;编码&#xff09;成可以传输的输出流&#xff08;字节流&#xff09;。而反序列化…

一文了解Java序列化与反序列化

目录 序列化示例有父类的对象序列化Serializable和Externalizable区别序列化和反序列化实现serialVersionUID不一致有什么问题1、先注释掉反序列化代码, 执行序列化代码, 然后User类新增一个属性sex2、再注释掉序列化代码执行反序列化代码3、指定serialVersionUID 序列化字段修…

一篇搞懂java序列化Serializable

序列化 (Serialization)将对象的状态信息转换为可以存储或传输的形式的过程。 一、序列化和反序列化的概念 把对象转换为字节序列的过程称为对象的序列化。 把字节序列恢复为对象的过程称为对象的反序列化。 对象的序列化主要有两种用途&#xff1a; 1&#xff09; 把对象…

Java序列化与数据传输

1&#xff09;什么是序列化 ① 序列化&#xff1a;Java 提供了一种对象序列化的机制&#xff0c;该机制中&#xff0c;一个对象可以被表示为一个字节序列&#xff0c;该字节序列包括该对象的数据、有关对象的类型的信息和存储在对象中数据的类型。 堆内存中的java对象数据&…

java序列化的作用

1.java序列化需要实现Serializaible接口或者Externalizable接口 2.java实现序列化的作用: 1.方便在远程调用时对象的解码与编码,就像new对象之间直接调用&#xff0c;不需要像传输对象之间像JSON转换一样转来转去 2.序列化的能力&#xff1a;为了在程序中能直接以对象的形式进…

Java序列化与反序列化

参考链接&#xff1a; Java 序列化与反序列化_Jacks丶的博客-CSDN博客_java反序列化 1 序列化与反序列化的概念 Java 序列化是指&#xff1a;将对象转化成一个字节序列(二进制数据)的过程。 将序列化对象写入文件之后&#xff0c;可以从文件中读取出来&#xff0c;并且对它…