Linux 文件与I/O操作
Andrew Huang <bluedrum@163>
课程内容
l系统调用write的返回值
l底层库函数
l标准库函数
l目录与文件维护
系统调用
l Linux 大部分的系统功能是通过系统调用(System Call)来实现的.如open,send之类.
l这些函数在C程序调用起来跟标准C库函数(printf…)非常类似.但是实现机制完全不同.
l库函数仍然是运行在Linux 用户空间程序.很多时候内部会调用系统调用.
l但系统调用是内核实现的.在C库封装成函数.但通过系统软中断进行调用.
–用time命令测试时间,系统时间实际就是系统调用时间累积
l time ./demo1
–用strace 可以跟踪一种程序系统调用使用情况
l strace ./demo1 #不需要调试信息
两者关系
l可以参考C库函数malloc与系统调用sbrk的关系
常见C标准库函数
l printf,getch,scanf
l strcpy,strcmp,strlen
l memcpy,memcmp,memset
l fopen,fwrite,fread
常见系统调用函数
l进程控制:fork(),waitpid()
l文件控制open(),write()
l网络收发函数socket(),bind(),send(),write()
l权限控制 access()
l标准C的函数,应该在MSDN和Linux下的man都能同时查联机帮助
–并且声明定义在stdlib.h当中
l而Linux系统调用只能用man查相应帮助
–大部分声明定义在unistd.h当中
文件控制
1. Linux文件结构
l Linux环境中的文件具有特别重要的意义,因为它们为操作系统服务和设备提供了一个简单而统一的接口.在Linux中,一切(或几乎一切)都是文件。
l通常程序完全可以像使用文件那样使用磁盘文件、串行口、打印机和其他设备。
l大多数情况下,你只需要使用五个基本的函数——open、close、read、write和ioctl l Linux中的任何事物都可以用一个文件代表,或者可以通过特殊的文件进行操作。
l一些特殊文件
–目录
–设备文件
–/dev/console
–/dev/tty
–/dev/null
2. 底层库函数
l Linux 在底层实现一整套处理文件函数.
–这一些函数能处理普通文件,网络socket文件,设备文件等
–全部是系统调用实现的函数
l文件处理函数
–open –打开或创建一个文件
–creat –建立一个空文件
–close –关闭一个文件
–read –从文件读入数据
–write –向文件写入一个数据
–lseek –在文件中移动读写位置
–unlink –删除一个文件
–remove –删除一个文件本身
–fcntl –控制一个文件属性
文件描述符
l值为一个非负整数
l用于表示一个打开文件
l在内核空间被引用,并且由系统调用(open)所创建
l read,write使用文件描述符
l内核缺省打开三个文件描述符
–1-标准输出
–2-错误输出
–0-标准输入
1)open –-- 打开或创建一个文件
open(打开文件)
相关函数read,write,fcntl,close,link,stat,umask,unlink,fopen
包含文件#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 标志位,参见下一页
返回值若所有欲核查的权限都通过了检查则返回0 值,表示成功,只要有一个权限被禁止则返回-1。
范例#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
main()
{
int fd,size;
char s [ ]=”Linux Programmer!\n”,buffer[80];
fd=open(“/tmp/temp”,O_WRONLY|O_CREAT);
write(fd,s,sizeof(s));
close(fd);
fd=open(“/tmp/temp”,O_RDONLY);
size=read(fd,buffer,sizeof(buffer));
close(fd);
printf(“%s”,buffer);
}
open的标志位
l flags可以去下面的一个值或者是几个值的组合.
–O_WRONLY 以只写方式打开文件
–O_RDONLY 以只读方式打开文件
–O_RDWR 以可读写方式打开文件。上述三种旗标是互斥的,也就是不可同时使用,但可与下列的旗标利用OR(|)运算符组合。
–O_CREAT 若欲打开的文件不存在则自动建立该文件。
–O_EXCL 如果O_CREAT 也被设置,此指令会去检查文件是否存在。文件若不存在则建立该文件,否则将导致打开文件错误。此外,若O_CREAT与O_EXCL同时设置,并且欲打开的文件为符号连接,则会打开文件失败。
–O_TRUNC 若文件存在并且以可写的方式打开时,此旗标会令文件长度清为0,而原来存于该文件的资料也会消失。
–O_APPEND 当读写文件时会从文件尾开始移动,也就是所写入的数据会以附加的方式加入到文件后面。
–O_NONBLOCK 以不可阻断的方式打开文件,也就是无论有无数据读取或等待,都会立即返回进程之中。
多进程open同一个文件
l open的打开的文件描述符,只在同一进程内是唯一的.换句话说,不同程序打开同名文件将会产生不同的描述符.
l不同进程写同一个文件会产生互相覆盖情况,大部分情况是无法预知.这是相当危险的情况,一般要加入互锁和进程间通讯来防止这种情况发生.
open mode标志位情况
l如果使用了O_CREATE标志,那么我们要使用open的第二种形式.,mode用来表示文件的访问权限. (sys/stat.h.中定义)
–S_IRUSR 用户可以读S_IWUSR 用户可以写
–S_IXUSR 用户可以执行S_IRWXU 用户可以读写执行
–S_IRGRP 组可以读S_IWGRP 组可以写
–S_IXGRP 组可以执行S_IRWXG 组可以读写执行
–S_IROTH 其他人可以读S_IWOTH 其他人可以写
–S_IXOTH 其他人可以执行S_IRWXO 其他人可以读写执行–S_ISUID 设置用户执行ID S_ISGID 设置组的执行ID
l我们也可以用数字来代表各个位的标志.Linux总共用5个数字来表示文件的各种权限.
00000.第一位表示设置用户ID.第二位表示设置组ID,第三位表示用户自己的权限位,第四位表示组的权限,最后一位表示其他人的权限.
open返回值
l错误代码
–成功打开文件返回文件描述符,否则返回一个负数
–EEXIST 参数pathname 所指的文件已存在,却使用了O_CREAT和O_EXCL标志。
–EACCESS 参数pathname所指的文件不符合所要求测试的权限。
–EROFS 欲测试写入权限的文件存在于只读文件系统内。
–EFAULT 参数pathname指针超出可存取内存空间。
–EINVAL 参数mode 不正确。
–ENAMETOOLONG 参数pathname太长。
–ENOTDIR 参数pathname不是目录。
–ENOMEM 核心内存不足。
–ELOOP 参数pathname有过多符号连接问题。
–EIO I/O 存取错误。
2)close –关闭一个文件
close(关闭文件)
相关函数open,fcntl,shutdown,unlink,fclose
表头文件#include<unistd.h>
定义函数int close(int fd);
函数说明当使用完文件后若已不再需要则可使用close()关闭该文件,二close()会让数据写回磁盘,并释放该文件所占用的资源。参数fd为先前由
open()或creat()所返回的文件描述词。
返回值若文件顺利关闭则返回0,发生错误时返回-1。
错误代码EBADF 参数fd 非有效的文件描述词或该文件已关闭。
附加说明虽然在进程结束时,系统会自动关闭已打开的文件,但仍建议自行关闭文件,并确实检查返回值。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。