Linux下文件IO操作

本文详细介绍了Linux系统中的文件IO操作,包括文件的概念、IO类型、系统IO与标准IO的区别、文件描述符的使用及open函数的参数。通过实践示例,解释了如何打开、关闭文件以及文件描述符的分配机制,强调了正确管理文件描述符的重要性。
摘要由CSDN通过智能技术生成

一、文件IO学习大纲。

1、文件IO概念、文件概念、文件类型。
2、访问文件方法一  -> 系统IO  打开?/读取?/写入?/关闭?
3、系统IO文件描述符概念?文件描述符与文件的关系?文件描述符的值。
4、文件偏移量概念。
5、系统IO应用实例:LCD液晶、触摸屏。
6、系统IO另外一种访问文件的方式:内存映射。 -> 针对LCD液晶
7、访问文件方法二  -> 标准IO  打开?/读取?/写入?/关闭? 
8、标准IO函数:处理字符/字符串
9、目录IO:访问目录,切换目录,读取目录,关闭目录。

二、文件IO概念?

1、什么是文件?

在linux下,一切都是文件。
除了我们平时常见的文件:1.txt/2.jpg/3.bmp/4.mp3是文件之外,linux系统还会把硬件设备当作是文件,例如:LED灯、触摸屏、LCD液晶屏幕,蜂鸣器,ADC,这些硬件设备在linux的眼中,都是文件来的。

2、什么是IO?

IO -> input/output -> 输入/输出
文件IO -> 对文件数据输入/输出 -> 写入数据到文件/从文件中读取数据出来。

3、如何实现文件读取/写入?

不需要用户写自定义函数,因为在linux下,已经有现成的函数来实现。

访问文件方式有两种:
系统IO -> 系统调用 -> 2 System calls -> 系统IO接口都是在第2手册。
标准IO -> 库调用 -> 3 Library calls -> 标准IO接口都是在第3手册。

4、使用系统IO与标准IO访问有什么区别?

系统IO来处理文件,没有缓冲区,直接按字节来处理。
标准IO来处理文件,有缓冲区,按块来处理。

作用对象:
访问硬件设备文件时(LED灯、触摸屏、LCD液晶) -> 直接使用系统IO来处理。
例如: 写一个温湿度传感器驱动 -> 使用系统IO来访问温湿度传感器驱动

访问普通文件(1.txt/2.bmp/3.jpg/4.mp3) -> 标准IO来处理。
例如:访问test.txt这个文件 -> 使用标准IO来访问。

5、文件类型 --> 7种

‘-’ 普通文件 -> 标准IO
‘d’ 目录文件 -> 目录IO(属于标准IO)
‘l’ 链接文件
‘p’ 管道文件 -> 系统IO
‘s’ 套接字文件 -> 需要使用网络编程接口访问
‘c’ 字符设备文件 -> 系统IO
‘b’ 块设备文件 -> 系统IO

三、如何使用系统IO访问文件?

1、如何打开文件? -> open() -> man 2 open

函数功能:open and possibly create a file
//打开和创建文件。

头文件:

	#include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>

函数原型:

	int open(const char *pathname, int flags);
    int open(const char *pathname, int flags, mode_t mode);

参数:
pathname:需要打开的那个文件的路径名。 (绝对路径/相对路径)
flags:
O_RDONLY:只读
O_WRONLY:只写
O_RDWR:可读可写

返回值:
成功:新的文件描述符file descriptor(其实就是一个最小,非负整数,没有使用过的)
失败:-1

注意:open函数什么时候会打开失败?
1)你打开的路径不存在时。
2)如果文件本身的权限不允许,那么操作权限不对,也会失败。
例如: 文件本身的权限: “-wx-wx-wx”,如果以O_RDONLY/O_RDWR去打开文件,那么就会失败。

2、如何关闭文件? -> close() -> man 2 close

函数功能:close a file descriptor
//关闭掉一个文件描述符

头文件:

 #include <unistd.h>

函数原型:

int close(int fd);

参数:
fd:需要关闭的那个文件的文件描述符。

返回值:
成功:0
失败:-1

练习1: 写程序,访问家目录下test.txt,如果访问成功,则输出"open file success",否则输出"open file error",并关闭文件,如果关闭成功,则输出"close file success",否则输出"close file error"。
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

int main(int argc,char *argv[])
{
	int fd,ret;
	fd = open("/home/gec/test.txt",O_RDWR);
	if(fd >= 0)
	{
		printf("open file suceess!\n");
	}
	else{
		printf("open file error!\n");
	}
	printf("fd = %d\n",fd);
	
	ret = close(fd);
	if(ret == 0)
	{
		printf("close file success!\n");
	}
	else{
		printf("close file error!\n");
	}
	
	return 0;
}
练习2: 看看访问之后的那个文件的文件描述符是多少? -> 3
练习3: 尝试访问一下开发板中/dev/fb0这个文件,访问之后就关闭它。
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

int main(int argc,char *argv[])
{
	int fd;
	fd = open("/dev/fb0",O_RDWR);
	if(fd < 0)
	{
		printf("open file error!\n");
	}
	
	close(fd);
	
	return 0;
}

四、文件描述符?

1、什么是文件描述符?

文件描述符是open函数的返回值,当open()执行成功时,就会返回非负,最小,没有使用过的整数。
例如:
3=open(“1.txt”); //3就是代表这个1.txt这个文件。
4=open(“2.txt”); //4就是代表这个2.txt这个文件。
A105=open(“关国源”) //A105就是代表这个关国源这个文件。

结论:将来需要处理文件时,我们不需要提供文件名字,只需要提供文件对应的文件描述符就可以。

2、访问文件时,发送fd从3开始分配,说明0/1/2已经被占用,究竟是谁在占用?

其实在系统启动时,就会默认打开3个文件,分别是"标准输入",“标准输出”,“标准出错”,他们其实是一个宏定义来的,是被定义在一个头文件中,头文件路径:/usr/include/unistd.h

/* Standard file descriptors. */

#define	STDIN_FILENO	0	//标准输入  -> 对象:键盘
#define	STDOUT_FILENO	1	//标准输出  -> 对象:屏幕
#define	STDERR_FILENO	2	//标准出错  -> 对象:屏幕

可以理解: 只要系统启动, 0 = open(“标准输入”)

3、举例子。

假设当前目录下有:a.txt b.txt c.txt d.txt
打开a.txt
打开b.txt
打开c.txt
关闭b.txt
打开d.txt
关闭a.txt
关闭c.txt
打开a.txt
打开c.txt
关闭d.txt
打开d.txt -> 返回值是多少? --> 4

结论:打开一个文件时候,就会得到一个文件描述符。 -> 申请资源
关闭一个文件时候,这个文件对应的文件描述符就可以被别人使用。-> 释放资源

4、研究文件描述符有没有最大值?
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

int main(int argc,char *argv[])
{
	int fd;
	while(1)
	{
		fd = open("./a.txt",O_RDWR);
		printf("fd = %d\n",fd);
		if(fd == -1)
		{
			break;
		}
	}
	return 0;
}

范围:0~1023。
记住:打开文件之后,记得要关闭!

五、open函数的拓展参数。
   int open(const char *pathname, int flags, mode_t mode);

pathname:需要打开的文件的路径
flags:
必选(三选一)
O_RDONLY:只读
O_WRONLY:只写
O_RDWR:可读可写

可选(0个/多个) -> 如果选了,就是使用了位或"|"来添加。
O_APPEND:以追加的方式打开文件,在每一次写数据之前,文件的定位都是在末尾。
O_CREAT:如果文件不存在,就会创建。
如果flags中有O_CREAT,那么mode这个参数就一定要填。
如果flags中没有O_CREAT,那么mode这个参数就算你填了,也没用。

O_TRUNC:如果文件存在并且是一个普通文件,而且打开方式必须是O_RDWR/O_WRONLY,那么这个文件就会被清空。

例子1:测试O_CREAT是否能创建文件。

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

int main(int argc,char *argv[])
{
	umask(0000);
	
	int fd;
	fd = open("/home/gec/ggy_test.txt",O_RDWR|O_CREAT,0777);
	if(fd < 0)
	{
		printf("open error!\n");
	}
	
	close(fd);
	
	return 0;
}

如果文件是存在的:
O_CREAT -> 不创建,打开成功
O_CREAT|O_EXCL -> 不创建,打开失败 O_EXCL就是要确保O_CREAT这个参数创建了才会生效!

如果文件是不存在的:
O_CREAT -> 创建文件并且打开成功
O_CREAT|O_EXCL -> 创建文件并且打开成功

例子2: 测试O_TRUNC能不能清空?

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

int main(int argc,char *argv[])
{
	umask(0000);
	
	int fd;
	fd = open("./a.txt",O_RDWR|O_TRUNC);
	if(fd < 0)
	{
		printf("open error!\n");
	}
	
	close(fd);
	
	return 0;
}

一般地,O_CREAT|O_TRUNC 连用,会有什么效果?
100%确保运行之后文件是存在的,并且是空白的!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值