Linux C库之- 文件操作篇

来源:互联网 发布:淘宝分享到微信怎么弄 编辑:程序博客网 时间:2024/06/05 12:24

相关函数 open、close、fopen、fclose、read、write、fread、fwrite、fcntl、link、unlink、stat、umask、

头文件 <sys/types.h>   基本数据类型

caddr_t 核心地址。clock_t 表示系统时间(以时钟周期为单位)。comp_t 压缩的时钟滴答。dev_t 用于设备号。fd_set 文件描述集。
fpos_t 文件位置。gid_t 数组值ID。ino_t  i节点编号。off_t 用于文件大小和偏移量。mode_t  文件类型,文件创建模式。
pid_t 进程ID和进程组IDptrdiff_t 是一种带符号整型,用于对两个指针执行减法运算后所得的结果。rlim_t 资源限制;
size_t 反映内存中对象的大小(以字节为单位)。ssize_t 供返回字节计数或错误提示的函数使用。time_t 以秒为单位计时。
uid_t 数值用户ID。wchar_t 能表示所有不同的字符码。
所有这些类型在 ILP32 编译环境中保持为 32 位值,并会在 LP64 编译环境中增长为 64 位值。

 <sys/stat.h>     文件状态 如ls -l

<fcntl.h>  定义了很多宏和函数原型


 

 int close(int fd)                          <unistd.h>

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


int open(const char *pathname, int flags,  mode_t mode)  <sys/types.h><sys/stat.h><sys/fcntl.h>

返回值

调用成功:返回文件描述符(整型变量0~255)。由open 返回的文件描述符一定是该进程尚未使用的最小描述符。

2.失败:只要有一个权限被禁止则返回-1。


flags: O_RDONLY  O_WRONLY  O_RDWR  //此3种互斥,只能用其中一种,但可与以下一起|

 O_CREAT 若欲打开的文件不存在则自动建立该文件。 

  O_EXCL 如果O_CREAT 也被设置,此指令会去检查文件是否存在。文件若不存在则建立该文件,否则将导致打开文件错误。此外,若O_CREAT与O_EXCL同时设置,并且欲打开的文件为符号连接,则会打开文件失败。

  O_NOCTTY 如果欲打开的文件为终端机设备时,则不会将该终端机当成进程控制终端机。

  O_TRUNC 若文件存在并且以可写的方式打开时,此旗标会令文件长度清为0,而原来存于该文件的资料也会消失。

  O_APPEND 当读写文件时会从文件尾开始移动,也就是所写入的数据会以附加的方式加入到文件后面。

  O_NONBLOCK 以不可阻断的方式打开文件,也就是无论有无数据读取,都会立即返回进程之中(非阻塞I/O使我

们的操作要么成功,要么立即返回错误,不被阻塞)。

O_NDELAY 同O_NONBLOCK。 O_SYNC 以同步的方式打开文件。

O_NOFOLLOW 如果参数pathname 所指的文件为一符号连接,则会令打开文件失败。

O_DIRECTORY 如果参数pathname 所指的文件并非为一目录,则会令打开文件失败

.参数modeS_

IRWXU  00700 权限,代表该文件所有者具有可读、可写及可执行的权限

S_IRUSR 或S_IREAD,00400权限,代表该文件所有者具有可读取的权限。

S_IWUSR 或S_IWRITE,00200 权限,代表该文件所有者具有可写入的权限。

S_IXUSR 或S_IEXEC,00100 权限,代表该文件所有者具有可执行的权限。

S_IRWXG 00070权限,代表该文件用户组具有可读、可写及可执行的权限。

S_IRGRP 00040 权限,代表该文件用户组具有可读的权限。

S_IWGRP 00020权限,代表该文件用户组具有可写入的权限。

S_IXGRP 00010 权限,代表该文件用户组具有可执行的权限。

S_IRWXO 00007权限,代表其他用户具有可读、可写及可执行的权限。

S_IROTH 00004 权限,代表其他用户具有可读的权限 S_IWOTH 00002权限,代表其他用户具有可写入的权限。 S_IXOTH 00001 权限,代表其他用户具有可执行的权限

错误代码

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

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

 EROFS 欲测试写入权限的文件存在于只读文件系统内。  EFAULT 参数pathname指针超出可存取内存空间。

 EINVAL 参数mode 不正确。  ENAMETOOLONG 参数pathname太长。  ENOTDIR 参数pathname不是目录。 

 ENOMEM 核心内存不足。  ELOOP 参数pathname有过多符号连接问题。   EIO I/O 存取错误。


FILE *fp;
fp=fopen("file a","r");
其意义是在当前目录下打开文件file a,只允许进行“读”操作,并使fp指向该文件。
又如:
FILE *fphzk
fphzk=fopen("c:\\hzk16","rb");
其意义是打开C驱动器磁盘的根目录下的文件hzk16,这是一个二进制文件,只允许按二进制方式进行读操作。两个反斜线“\\ ”中的第一个表示转义字符,第二个表示根目录。
意义
"r"打开一个用于读取的文本文件 "w"创建一个用于写入的文本文件"a"附加到一个文本文件
"rb"打开一个用于读取的二进制文件 "wb"创建一个用于写入的二进制文件"ab"附加到一个二进制文件
"r+"打开一个用于读/写的文本文件 "w+"创建一个用于读/写的文本文件"a+"打开一个用于读/写的文本文件
“rt”只读打开一个文本文件,只允许读数据 “wt”只写打开或建立一个文本文件,只允许写数据
“at”追加打开一个文本文件,并在文件末尾写数据 “rb”只读打开一个二进制文件,只允许读数据
“wb”只写打开或建立一个二进制文件,只允许写数据“ab”追加打开一个二进制文件,并在文件末尾写数据
“rt+”读写打开一个文本文件,允许读和写 “wt+”读写打开或建立一个文本文件,允许读写
“at+”读写打开一个文本文件,允许读,或在文件末追加数据 “rb+”读写打开一个二进制文件,允许读和写
“wb+”读写打开或建立一个二进制文件,允许读和写“ab+”读写打开一个二进制文件,允许读,或在文件末追加数据
注:r(read): 读 w(write): 写a(append): 追加 t(text): 文本文件,可省略不写b(binary): 二进制文件 +: 读和写

2) 凡用“r”打开一个文件时,该文件必须已经存在,且只能从该文件读出。
3) 用“w”打开的文件只能向该文件写入。若打开的文件不存在,则以指定的文件名建立该文件,若打开的文件已经存在,则将该文件删去,重建一个新文件。
4) 若要向一个已存在的文件追加新的信息,只能用“a”方式打开文件。但此时该文件必须是存在的,否则将会出错。
5) 在打开一个文件时,如果出错,fopen将返回一个空指针值NULL。

 int fclose(FILE *stream);

关闭一个流。注意:使用fclose()函数就可以把缓冲区内最后剩余的数据输出到磁盘文件中,并释放文件指针和有关的缓冲区。

如果流成功关闭,fclose 返回 0,否则返回EOF(-1)。如果流为NULL,而且程序可以继续执行,fclose设定error number给EINVAL,并返回EOF。

ssize_t read(int fd, void *buf, size_t count);                      #include <unistd.h>    
返回值:成功返回读取的字节数,出错返回-1并设置errno,如果在调read之前已到达文件末尾,则这次read返回0
count:是请求读取的字节数,读上来的数据保存在缓冲区buf中,同时文件的当前读写位置向后移。注意这个读写位置和使用C标准I/O库时的读写位置有可能不同,这个读写位置是记在内核中的,而使用C标准I/O库时的读写位置是用户空间I/O缓冲区中的位置。比如用fgetc读一个字节,fgetc有可能从内核中预读1024个字节到I/O缓冲区中,再返回第一个字节,这时该文件在内核中记录的读写位置是1024,而在FILE结构体中记录的读写位置是1。注意返回值类型是ssize_t,表示有符号的size_t,这样既可以返回正的字节数、0(表示到达文件末尾)也可以返回负值-1(表示出错)。read函数返回时,返回值说明了buf中前多少个字节是刚读上来的。有些情况下,实际读到的字节数(返回值)会小于请求读的字节数count,例如:读常规文件时,在读到count个字节之前已到达文件末尾。例如,距文件末尾还有30个字节而请求读100个字节,则read返回30,下次read将返回0。

从终端设备读,通常以行为单位,读到换行符就返回了

从网络读,根据不同的传输层协议和内核缓存机制,返回值可能小于请求的字节数,后面socket编程部分会详细讲解

ssize_t write(int fd, const void *buf, size_t count);                        #include <unistd.h>   
返回值:成功返回写入的字节数,出错返回-1并设置errno写常规文件时,write的返回值通常等于请求写的字节数count,而向终端设备或网络写则不一定。

读常规文件是不会阻塞的,不管读多少字节,read一定会在有限的时间内返回。从终端设备或网络读则不一定,如果从终端输入的数据没有换行符,调用read读终端设备就会阻塞,如果网络上没有接收到数据包,调用read从网络读就会阻塞,至于会阻塞多长时间也是不确定的,如果一直没有数据到达就一直阻塞在那里。同样,写常规文件是不会阻塞的,而向终端设备或网络写则不一定。

现在明确一下阻塞(Block)这个概念。当进程调用一个阻塞的系统函数时,该进程被置于睡眠(Sleep)状态,这时内核调度其它进程运行,直到该进程等待的事件发生了(比如网络上接收到数据包,或者调用sleep指定的睡眠时间到了)它才有可能继续运行。与睡眠状态相对的是运行(Running)状态,在Linux内核中,处于运行状态的进程分为两种情况:

正在被调度执行。CPU处于该进程的上下文环境中,程序计数器(eip)里保存着该进程的指令地址,通用寄存器里保存着该进程运算过程的中间结果,正在执行该进程的指令,正在读写该进程的地址空间。

就绪状态。该进程不需要等待什么事件发生,随时都可以执行,但CPU暂时还在执行另一个进程,所以该进程在一个就绪队列中等待被内核调度。系统中可能同时有多个就绪的进程,那么该调度谁执行呢?内核的调度算法是基于优先级和时间片的,而且会根据每个进程的运行情况动态调整它的优先级和时间片,让每个进程都能比较公平地得到机会执行,同时要兼顾用户体验,不能让和用户交互的进程响应太慢。


size_t fread ( void   *buffer,  size_t size,  size_t count,  FILE *stream) ;    《stdio.h》
从一个文件流中读数据,最多读取count个元素,每个元素size字节,如果调用成功返回实际读取到的元素个数,如果不成功返回 0。
size_t fread ( void   *buffer,  size_t size,  size_t count,  FILE *stream) ;
从一个文件流中读数据,最多读取count个元素,每个元素size字节,如果调用成功返回实际读取到的元素个数,如果不成功返回 0。

注意:1 完成次写操(fwrite())作后必须关闭流(fclose());

           2 完成一次读操作(fread())后,如果没有关闭流(fclose()),则指针(FILE * fp)自动向后移动前一次读写的长度,不关闭流继续下一次读操作则接着上次的输出继续输出;

           3 fprintf() : 按格式输入到流,其原型是int fprintf(FILE *stream, const char *format[, argument, ...]);其用法和printf()相同,不过不是写到控制台,而是写到流罢了。注意的是返回值为此次操作写入到文件的字节数。如int c = fprintf(fp, "%s %s %d %f", str1,str2, a, b) ;str1:10字节;str2: 10字节;a:2字节;b:8字节,c为33,因为写入时不同的数据间自动加入一个空格。


int fcntl(int fd, int cmd); 
  int fcntl(int fd, int cmd, long arg); 
  int fcntl(int fd, int cmd, struct flock *lock);
fcntl()用来操作文件描述符的一些特性。fcntl 不仅可以施加建议性锁,还可以施加强制锁。同时,fcntl还能对文件的某一记录进行上锁,也就是记录锁。
fcntl的返回值与命令有关。如果出错,所有命令都返回-1,如果成功则返回某个其他值。下列四个命令有特定返回值:F_DUPFD、F_GETFD、F_GETFL、F_GETOWN.第一个返回新的文件描述符,接下来的两个返回相应标志,最后一个返回一个正的进程ID或负的进程组ID。
fcntl()针对(文件)描述符提供控制.参数fd 是被参数cmd操作(如下面的描述)的描述符.
  针对cmd的值,fcntl能够接受第三个参数int arg

参数fd

参数fd代表欲设置的文件描述词。

参数cmd

参数cmd代表打算操作的指令。
有以下几种情况:
F_DUPFD用来查找大于或等于参数arg的最小且仍未使用的文件描述词,并且复制参数fd的文件描述词。执行成功则返回新复制的文件描述词。新描述符与fd共享同一文件表项,但是新描述符有它自己的一套文件描述符标志,其中FD_CLOEXEC文件描述符标志被清除。请参考dup2()。
F_GETFD取得close-on-exec旗标。若此旗标的FD_CLOEXEC位为0,代表在调用exec()相关函数时文件将不会关闭。
F_SETFD 设置close-on-exec 旗标。该旗标以参数arg 的FD_CLOEXEC位决定。
F_GETFL 取得文件描述词状态旗标,此旗标为open()的参数flags。
F_SETFL 设置文件描述词状态旗标,参数arg为新旗标,但只允许O_APPEND、O_NONBLOCK和O_ASYNC位的改变,其他位的改变将不受影响。
F_GETLK 取得文件锁定的状态。
F_SETLK 设置文件锁定的状态。此时flcok 结构的l_type 值必须是F_RDLCK、F_WRLCK或F_UNLCK。如果无法建立锁定,则返回-1,错误代码为EACCES 或EAGAIN。
F_SETLKW F_SETLK 作用相同,但是无法建立锁定时,此调用会一直等到锁定动作成功为止。若在等待锁定的过程中被信号中断时,会立即返回-1,错误代码为EINTR。

参数lock指针

参数lock指针为flock 结构指针,定义如下
struct flock
{
short int l_type;
short int l_whence;
off_t l_start;
off_t l_len;
pid_t l_pid;
};
l_type 有三种状态:
F_RDLCK 建立一个供读取用的锁定
F_WRLCK 建立一个供写入用的锁定
F_UNLCK 删除之前建立的锁定
l_whence 也有三种方式:
SEEK_SET 以文件开头为锁定的起始位置。
SEEK_CUR 以目前文件读写位置为锁定的起始位置
SEEK_END 以文件结尾为锁定的起始位置。
返回值 成功则返回0,若有错误则返回-1,错误原因存于errno







原创粉丝点击