Linux文件IO操作
文件操作
- 1、系统调用概述
- 2、系统调用 和 库函数的区别(重要!!!)
- 3、文件描述符(重要!!!)
- 案例:读取文件数据
- 4、文件的打开读写关闭
- 4.1、打开文件open
- 4.1.1、flags宏的介绍(打开方式)
- 4.1.2、mode的介绍(权限)
- 4.2、关闭文件close
- 案例:
- 4.3、文件的写操作write
- 4.4、read读取文件数据
- 案例:读文件数据
- 案例:实现cp命令: cp src_file dst_dir
- 5、文件的阻塞特性
- 案例:默认终端是读是阻塞的
- 案例:非阻塞()
- 5.1、通过fcntl函数设置文件的阻塞特性(了解)
- 案例:默认阻塞
- 6、通过文件名 直接获取文件的状态(了解)
- 案例:
- 7、文件的目录操作(了解)
- 1、打开文件目录opendir
- 2、读取目录readdir 调用一次 只能读取一个文件
- 3、关闭closedir
- 案例:
1、系统调用概述
系统调用,顾名思义,说的是操作系统提供给用户程序调用的一组“特殊”接口。(重要!!!)
一个进程(用户态、内核态)(了解)
2、系统调用 和 库函数的区别(重要!!!)
系统调用是需要时间的,程序中频繁的使用系统调用会降低程序的运行效率。当运行内核代码时,CPU工作在内核态,在系统调用发生前需要保存用户态的栈和内存环境,然后转入内核态工作。系统调用结束后,又要切换回用户态。这种环境的切换会消耗掉许多时间 。
3、文件描述符(重要!!!)
用一个非负整数 来标识一个文件 这个非负的整数 就是文件描述符。
打开一个文件 系统就会为我们非配一个文件描述符 操作文件描述符 就等价于 操作文件.
文件描述符表:进程运行的时候 系统创建文件描述符表 来管理系统中文件描述符。
每一个进程 默认打开了3个文件描述符(0标准输入设备/键盘 1标准输出设备/屏幕 2标准错误输出/屏幕)
案例:读取文件数据
运行结果:
当用户打开一个文件的时候 系统 会给我们分配一个最小可用的文件描述符(重要!!!)
文件描述符表的管理(位图)
4、文件的打开读写关闭
4.1、打开文件open
#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);//打开不存在的文件
//flags:read write操作文件的权限
//mode:该文件在磁盘中 相对于 用户的权限
功能:打开文件,如果文件不存在则可以选择创建。
参数:pathname:文件的路径及文件名flags:打开文件的行为标志,必选项 O_RDONLY, O_WRONLY, O_RDWRmode:这个参数,只有在文件不存在时有效,指新建文件时指定文件的权限
返回值:成功:成功返回打开的文件描述符失败:-1
4.1.1、flags宏的介绍(打开方式)
比如:以读写的方式打开 不存在则创建 存在清空 flags=O_RDWR | O_CREAT | O_TRUNC
4.1.2、mode的介绍(权限)
mode的权限分3组:所拥有者、同组用户、其他用户
每组都必须有独立的权限。
4表示读r 2表示写w 1表示可执行x
文件的最终权限 = 默认权限 - 文件掩码
文件掩码:屏蔽其他用户的权限
chmod 777 xxx将xxx的最终权限设置为777
4.2、关闭文件close
#include <unistd.h>
int close(int fd);
功能:关闭已打开的文件
参数:fd : 文件描述符,open()的返回值
返回值:成功:0失败: -1, 并设置errno
案例:
运行结果:
4.3、文件的写操作write
#include <unistd.h>
ssize_t write(int fd, const void *buf, size_t count);
功能:把指定数目的数据写到文件(fd)
参数:fd : 文件描述符buf : 数据首地址count : 写入数据的长度(字节)
返回值:成功:实际写入数据的字节个数失败: - 1
4.4、read读取文件数据
#include <unistd.h>
ssize_t read(int fd, void *buf, size_t count);
功能:把指定数目的数据读到内存(缓冲区)
参数:fd : 文件描述符buf : 内存首地址count : 读取的字节个数
返回值:成功:实际读取到的字节个数失败: - 1 文件末尾返回0
案例:读文件数据
案例:实现cp命令: cp src_file dst_dir
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
int main(int argc, char *argv[])
{//./main test.txt testif(argc != 3){printf("please intput:./main src dst_dir\n");}char src_file[128]="";char dst_file[128]="";strcpy(src_file, argv[1]);//test.txtsprintf(dst_file,"%s/%s",argv[2], argv[1]);//"test/test.txt"int fd1 = open(src_file, O_RDONLY);if(fd1 < 0){perror("open");return 0;}int fd2 = open(dst_file, O_WRONLY|O_CREAT,0777);if(fd2 <0){perror("open");return 0;}while(1){char buf[128]="";//从s源文件中读取数据int ret = read(fd1,buf,sizeof(buf));if(ret <= 0)break;//将读到的w数据写到目的文件中write(fd2,buf,ret);}close(fd1);close(fd2);return 0;
}
运行结果:
5、文件的阻塞特性
【注意】阻塞与非阻塞是对于文件而言的,而不是指read、write等的属性
案例:默认终端是读是阻塞的
#include<stdio.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
int main(int argc,char *argv[])
{// /dev/tty --> 当前终端设备int fd = open("/dev/tty", O_RDONLY);//默认是阻塞的if(fd<0){perror("open");return 0;}printf("fd = %d\n",fd);char buf[128]="";printf("准备读!!!\n");read(fd,buf,sizeof(buf));printf("buf=%s\n",buf);close(fd);return 0;
}
运行结果:
案例:非阻塞()
#include<stdio.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
int main(int argc,char *argv[])
{// /dev/tty --> 当前终端设备//int fd = open("/dev/tty", O_RDONLY);//默认是阻塞的int fd = open("/dev/tty", O_RDONLY|O_NONBLOCK);//不阻塞的if(fd<0){perror("open");return 0;}printf("fd = %d\n",fd);char buf[128]="";printf("准备读!!!\n");read(fd,buf,sizeof(buf));printf("buf=%s\n",buf);close(fd);return 0;
}
运行结果:
5.1、通过fcntl函数设置文件的阻塞特性(了解)
我们还可以通过fcntl函数来设置文件描述符的阻塞特性
#include <unistd.h>
#include <fcntl.h>
int fcntl(int fd, int cmd, ... /* arg */);
功能:改变已打开的文件性质,fcntl针对描述符提供控制。
参数:fd:操作的文件描述符cmd:操作方式arg:针对cmd的值,fcntl能够接受第三个参数int arg。
返回值:成功:返回某个其他值失败:-1
fcntl函数有5种功能:
1) 复制一个现有的描述符(cmd=F_DUPFD)
2) 获得/设置文件描述符标记(cmd=FGETFD或FSETFD)
3) 获得/设置文件状态标记(cmd=FGETFL或FSETFL)
4) 获得/设置异步I/O所有权(cmd=FGETOWN或FSETOWN)
5) 获得/设置记录锁(cmd=FGETLK, FSETLK或F_SETLKW)
案例:默认阻塞
fcntl函数设置非阻塞
#include<stdio.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
int main(int argc,char *argv[])
{char buf[128]="";//fcntl设置文件标记的3步曲//获得文件的标记int flag = fcntl(0, F_GETFL);//修改文件的标记(非阻塞标记)flag |= O_NONBLOCK;//设置文件的标记fcntl(0,F_SETFL, flag);printf("准备读!!!\n");read(0,buf,sizeof(buf));printf("buf=%s\n",buf); return 0;
}
运行结果:
6、通过文件名 直接获取文件的状态(了解)
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
int stat(const char *path, struct stat *buf);
int lstat(const char *pathname, struct stat *buf);
功能:获取文件状态信息stat和lstat的区别:当文件是一个符号链接时,lstat返回的是该符号链接本身的信息;而stat返回的是该链接指向的文件的信息。
参数:path:文件名buf:保存文件信息的结构体
返回值:成功: 0失败: -1
struct stat的结构信息:
struct stat {dev_t st_dev; //文件的设备编号ino_t st_ino; //节点mode_t st_mode; //文件的类型和存取的权限nlink_t st_nlink; //连到该文件的硬连接数目,刚建立的文件值为1uid_t st_uid; //用户IDgid_t st_gid; //组IDdev_t st_rdev; //(设备类型)若此文件为设备文件,则为其设备编号off_t st_size; //文件字节数(文件大小)blksize_t st_blksize; //块大小(文件系统的I/O 缓冲区大小)blkcnt_t st_blocks; //块数time_t st_atime; //最后一次访问时间time_t st_mtime; //最后一次修改时间time_t st_ctime; //最后一次改变时间(指属性)
};
st_mode(16位整数)参数说明:
案例:
#include<stdio.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
int main(int argc,char *argv[])
{struct stat my_stat;stat("test.txt", &my_stat);printf("文件的大小:%u\n", my_stat.st_size);if(S_ISREG(my_stat.st_mode)){printf("它是一个普通文件\n");}else if(S_ISDIR(my_stat.st_mode)){printf("它是一个目录文件\n");}if((my_stat.st_mode& S_IRUSR)== S_IRUSR){printf("所有者具备读的权限\n");}return 0;
}
运行结果:
7、文件的目录操作(了解)
我们经常需要读取一个目录下的所有文件名,所以一下介绍如何读取一个文件下的目录
步骤:
1、打开文件目录opendir
#include <sys/types.h>
#include <dirent.h>
DIR *opendir(const char *name);
功能:打开一个目录
参数:name:目录名
返回值:成功:返回指向该目录结构体指针失败:NULL
2、读取目录readdir 调用一次 只能读取一个文件
#include <dirent.h>
struct dirent *readdir(DIR *dirp);
功能:读取目录
参数:dirp:opendir的返回值
返回值:成功:目录结构体指针失败:NULL
struct dirent:
struct dirent
{ino_t d_ino; // 此目录进入点的inodeoff_t d_off; // 目录文件开头至此目录进入点的位移signed short int d_reclen; // d_name 的长度, 不包含NULL 字符unsigned char d_type; // d_type 所指的文件类型char d_name[256]; // 文件名
};
d_type取值:
3、关闭closedir
#include <sys/types.h>
#include <dirent.h>
int closedir(DIR *dirp);
功能:关闭目录参数:dirp:opendir返回的指针返回值:成功:0失败:-1
案例:
#include <stdio.h>
#include <dirent.h>
int main(int argc,char *argv[])
{//打开目录DIR *dir = opendir("test");if(dir == NULL){perror("opendir");return 0;}//读取目录while(1){struct dirent *p = readdir(dir);if(p == NULL)break;printf("文件名:%s ", p->d_name);if(p->d_type == DT_DIR){printf("目录\n");}else if(p->d_type == DT_REG){printf("普通文件\n");}}//关闭closedir(dir);
}
运行结果:
Linux文件IO操作相关推荐
- 嵌入式 Linux 文件IO操作
目录 Linux 文件操作 1 Linux 系统环境文件操作概念 2 缓冲 IO 文件操作 1 文件的创建,打开与关闭 fopen 函数函数 2 freopen 函数 3.fdopen函数 4.fcl ...
- linux的文件io操作(转)
linux文件IO操作有两套大类的操作方式:不带缓存的文件IO操作,带缓存的文件IO操作.不带缓存的属于直接调用系统调用(system call)的方式,高效完成文件输入输出.它以文件标识符(整型)作 ...
- 漫谈linux文件io,Linux文件IO与通用块层的请求合并
本文参考https://mp.weixin.qq.com/s/Imt4BW-zoHPpcOpcKZs_AQ, 公众号"Linux阅码场" 请求合并就是将进程内或者进程间产生的在物理 ...
- 【Linux系统编程】文件IO操作
文件描述符 在 Linux 的世界里,一切设备皆文件.我们可以系统调用中 I/O 的函数(I:input,输入:O:output,输出),对文件进行相应的操作( open().close().writ ...
- Linux基础(6)--文件IO操作
文件IO操作 1. open打开操作 2. close关闭操作 3. creat创建操作 4. write写操作 5. read读操作 Linux下一切皆文件,所以文件IO是很重要的也是很基础的操作. ...
- linux的每次IO大小控制,linux文件io缓冲
linux文件io缓冲 出于速度和效率考虑,系统io调用(即内核)和标准 C语言库的io函数(即 stdin 函数)在操作磁盘文件时会对数据进行缓冲. read(),write()系统调用在操作磁盘文 ...
- Linux文件IO深入剖析
文章目录 1 linux文件系统基本概念 1.1 文件系统基本概念 1.2 文件系统缓存 2 文件IO访问方式概述 2.1 标准文件IO 2.2 直接IO 2.3 缓存同步 1 linux文件系统基本 ...
- Linux 文件 IO
参考:http://blog.csdn.net/wanxiao009/article/details/5648583 C 和 C++ 文件操作详解:http://blog.csdn.net/freek ...
- 2.Linux文件IO编程
2.1Linux文件IO概述 2.1.0POSIX规范 POSIX:(Portable Operating System Interface)可移植操作系统接口规范. 由IEEE制定,是为了提高UNI ...
- 浅析 Linux 文件 IO 读写
浅析 Linux 文件 IO 读写 Linux的文件IO子系统是Linux中最复杂的一个子系统(没有之一).读者可以参考以下这个图: https://www.thomas-krenn.com/de/w ...
最新文章
- 宁可寸寸断,不意绕指柔
- 【OC】【一秒就会】【collectionView 头部吸住功能】
- [菜鸟SpringCloud实战入门]第七章:配置中心客户端主动刷新机制 + 配置中心服务化和高可用改造...
- 455. 分发饼干 golang
- Spring入门篇——第6章 Spring AOP的API介绍
- 【英语学习】【English L06】U02 Food L1 Food on the menu
- 理解分布式和集群的区别
- java家谱树_青锋家谱系统-基于springboot+orgtree的青锋家谱树管理系统
- java 数据类型 面试题_Java数据类型面试题目
- mysql必知必会第4版pdf百度网盘_SQL必知必会 第4版pdf
- 网上鞋店html,“鞋店”是“shoes store”还是“shoe store”?
- 樱花树代码html,樱花树代码
- android 查看cad方案,android 加载dwg 图纸解决方案
- c语言优先级详解pdf,C语言符号优先级.pdf
- Win10 设置锁屏壁纸提示尝试其它图片
- python 计算置信区间_python 计算数据中值的置信区间
- 【Python】计算VOC格式XML文件中目标面积和长宽比并生成直方图
- html显示一条直线,如何在HTML中画一条线
- 局域网环境下的直播平台(校园电视台)搭建之路
- 进程间通信——消息队列(Message queue)