Linux _文件操作
文件的作用
linux中,一切皆文件(网络设备除外)
硬件设备也“是”文件,通过文件来使用设备
目录(文件夹)也是一种文件Linux的文件结构
了解各主要文件夹的作用系统调用和设备驱动程序之间的关系
应用层的open, close, read, write, ioctl与驱动程序的关系文件操作方式
0) 文件描述符
是一个>=0的整数
每打开一个文件,就创建一个文件描述符,通过文件描述符来操作文件预定义的文件描述符: 0:标准输入,对应于已打开的标准输入设备(键盘) 1:标准输出,对应于已打开的标准输出设备(控制台) 2. 标准错误, 对应于已打开的标准错误输出设备(控制台) 多次打开同一个文件,可得到多个不同的文件描述符。
1) 使用底层文件操作(系统调用)
比如:read
可使用man 2 查看
2) 使用I/O库函数
比如:fread
可使用man 3 查看底层文件操作(关于文件的系统调用)
1) write(int fd , char* buff ,int size_t);
(1) 用法
man 2 write
(2) 返回值
成功:返回实际写入的字节数
失败:返回 -1
注意:是从文件的当前指针位置写入!
文件刚打开时,文件的位置指针指向文件头
实例:main1.c2) read
(1)用法
man 2 read(int fd, char * buff , int size_t);
(2)返回值0 : 实际读取的字节数
0 : 已读到文件尾
-1 :出错
注意:参数3表示最多能接受的字节数,而不是指一定要输入的字节数
实例:main2.c
运行:# ./a.out /* 用户输入回车符时结束输入 */
# ./a.out < main.c /* 利用重定向, 使用文件main.c作为输入 */3) open
(1) 用法
main 2 open
(2) 返回值
成功:文件描述符
失败:-1
(3) 打开方式
O_RDONLY 只读
O_WRONLY 只写
O_RDWR 读写
O_CREAT 如果文件不存在,则创建该文件,并使用第3个参数设置权限
O_EXCL 如果同时使用O_CREAT而且该文件又已经存在时,则返回错误
用途:以防止多个进程同时创建同一个文件
O_APPEND 尾部追加方式(打开后,文件指针指向文件的末尾)
O_TRUNCexample: open("/dev/hello", O_RDONLY|O_CREAT|O_EXCL, 0777) (4) 参数3 (设置权限) 当使用O_CREAT时,使用参数3 S_I(R/W/X)(USR/GRP/OTH) 例: S_IRUSR | S_IWUSR 文件的所有者对该文件可读可写 (八进制表示法)0600 文件的所有者对该文件可读可写 注意: 返回的文件描述符是该进程未打开的最小的文件描述符
4) close
(1) 用法
man 2 close(file_fd)终止指定文件描述符与对应文件之间的关联, 并释放该文件描述符,即该文件描述符可被重新使用 (2)返回值 成功: 0 失败: -1 实例: 使用read/write实现文件复制 main3.c main4.c 观察耗时 ./a.out time ./a.out 补充:time命令 time目录分别输出: 程序总的执行时间、 该程序本身所消耗的时间、 系统调用所消耗的时间
5) lseek
(1) 用法
man 2 lseek(file_fd , 要偏移字符数,文件指针定位 ) (文件指针是个结构体)
(2) 返回值
成功:返回新的文件位置与文件头之间偏移
失败: -1实例:拷贝一个文件尾部的100个字节到另一个文件 main5.c
6) ioctl
用来控制设备.
beep实例标准I/O库
直接使用系统调用的缺点
(1) 影响系统性能
系统调用比普通函数调用开销大
因为,系统调用要进行用户空间和内核空间的切换
(2) 系统调用一次所能读写的数据量大小,受硬件的限制解决方案: 使用带缓冲功能的标准I/O库(以减少系统调用次数)
/* C语言中的文件操作中已描述 */
1) fwrite
2) fread
3) fopen
4) fclose
5) fseek
6) fflushproc文件系统
/proc是一个特殊的文件系统,
该目录下文件用来表示与启动、内核相关的特殊信息1) /proc/cpuinfo
CPU详细信息2) /proc/meminfo
内存相关信息3) /proc/version
版本信息4) /proc/sys/fs/file-max
系统中能同时打开的文件总数
可修改该文件5) 进程的相关信息
/proc/32689/ 表示指定进程(进程号为32689)的相关信息6) /proc/devices
已分配的字符设备、块设备的设备号文件锁
1) 并发对文件I/O操作的影响
解决办法?
2)文件锁
用法:man 2 fcntl
文件锁的表示
struct flock详解:用法:
include<fctntl.h>
include<unistd.h>
int fcntl(int fd, int cmd);
int fcntl(int fd, int cmd, long arg);
int fcntl(int fd, int cmd, struct flock *lock);
参数:
fd:文件描述词。
cmd:操作命令。
arg:供命令使用的参数。
lock:同上。
有以下操作命令可供使用
一. F_DUPFD :复制文件描述词 。
二. FD_CLOEXEC :设置close-on-exec标志。如果FD_CLOEXEC位是0,执行execve的过程中,文件保持打开。反之则关闭。
三. F_GETFD :读取文件描述词标志。
四. F_SETFD :设置文件描述词标志。
五. F_GETFL :读取文件状态标志。
六. F_SETFL :设置文件状态标志。
其中O_RDONLY, O_WRONLY, O_RDWR, O_CREAT, O_EXCL, O_NOCTTY 和 O_TRUNC不受影响,
可以更改的标志有 O_APPEND,O_ASYNC, O_DIRECT, O_NOATIME 和 O_NONBLOCK。
七. F_GETLK, F_SETLK 和 F_SETLKW :获取,释放或测试记录锁,使用到的参数是以下结构体指针:
F_SETLK:在指定的字节范围获取锁(F_RDLCK, F_WRLCK)或者释放锁(F_UNLCK)。如果与另一个进程的锁操作发生冲突,返回 -1并将errno设置为EACCES或EAGAIN。
为了设置读锁,文件必须以读的方式打开。为了设置写锁,文件必须以写的方式打开。为了设置读写锁,文件必须以读写的方式打开。
struct flock 的设置:
struct flock flock;
flock.l_type = type; 文件锁 的类型 读锁 写锁
flock.l_whence = SEEK_SET; 定位
flock.l_start = 0; 偏移量
flock.l_len = 0; 读取长度
flock.l_pid = -1; 文件描述符
设置文件锁时 可以封装为一个函数 int flock_set(int fd, int type);
文件锁的操作 int fcntl(int fd, int cmd , struct flock *lock); cmd 获取 释放 测试
2)实例
main6.c