TLPI(liunx/unix系统编程手册)笔记 深入探究文件I/O

Posted AAAron

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了TLPI(liunx/unix系统编程手册)笔记 深入探究文件I/O相关的知识,希望对你有一定的参考价值。

本章的重点我想就是原子操作,避免在几个进程在打开同一文件的时候造成的错误,了解一下时间片的概念会对本章有所帮助。

(1)独占方式打开文件。(open     <-O_CREAT)

  知道,open,可以创建文件并返回fd。当我们的进程运行到open这个函数时间片到了,另一个进程也对这个路径的文件open,那么时间片结束后两个进程都会认为自己是这个文件的拥有者。并未是独占创建打开的。在open 函数的第二个参数中有 O_EXCL 这种打开方式,可以解决独占的问题。另外可以在多进程对一个文件写的时候,会出现offset混乱的情况,如果是在文件后写入的话,就用O_APPEND.

(2)相关函数。

  <1>fcntl()

NAME
       fcntl - manipulate file descriptor

SYNOPSIS
       #include <unistd.h>
       #include <fcntl.h>

       int fcntl(int fd, int cmd, ... /* arg */ );

 第三参数可以省略,根据二参数cmd来确定。具体的可以参考man手册。

 下面是man手册上的摘录:

   Duplicating a file descriptor  创建文件描述符的副本
       F_DUPFD (long)
              Find the lowest numbered available file descriptor greater than or equal to arg and make it be a copy of fd.  This is differ‐
              ent from dup2(2), which uses exactly the descriptor specified.
              创建的副本的文件描述符是当前系统里最大的加一。dup2之后会说
              On success, the new descriptor is returned.
         返回值是新的文件描述符
       F_DUPFD_CLOEXEC (long; since Linux 2.6.24)
              As for F_DUPFD, but additionally set the close-on-exec flag for the duplicate descriptor.  Specifying  this  flag  permits  a
              program  to avoid an additional fcntl() F_SETFD operation to set the FD_CLOEXEC flag.  For an explanation of why this flag is
              useful, see the description of O_CLOEXEC in open(2).复制时增加O_CLOEXEC标志

  

   File descriptor flags  获取修改访问模式和状态标志
       The following commands manipulate the flags associated  with  a  file  descriptor.   Currently,  only  one  such  flag  is  defined:
       FD_CLOEXEC, the close-on-exec flag.  If the FD_CLOEXEC bit is 0, the file descriptor will remain open across an execve(2), otherwise
       it will be closed.
  File status flags
    Each open file description has certain associated status flags, initialized by open(2) and possibly modified by fcntl(). Duplicated
    file descriptors (made with dup(2), fcntl(F_DUPFD), fork(2), etc.) refer to the same open file description, and thus share the same
    file status flags.

 


       F_GETFD (void)  获取
              Read the file descriptor flags; arg is ignored.

       F_SETFD (long)  修改
              Set the file descriptor flags to the value specified by arg.

  修改O_RDONLY和O_WRONLY是需要注意,并不是像mask一样,它是按顺序设置宏的。需要与上O_ACCMODE。

  还有很多。。。就不一一列举,用到直接man手册

  <2>dup()--dup2()

  复制一个fd。

  dup2复制并替换成参数二。

       #include <unistd.h>

       int dup(int oldfd);
       int dup2(int oldfd, int newfd);

       #define _GNU_SOURCE             /* See feature_test_macros(7) */
       #include <unistd.h>

       int dup3(int oldfd, int newfd, int flags);

    <3>pread() and pwrite()

    不影响offset的原子读写操作适合多线程。

       #include <unistd.h>

       ssize_t pread(int fd, void *buf, size_t count, off_t offset);

       ssize_t pwrite(int fd, const void *buf, size_t count, off_t offset);

    <4>readv() and writev()

    矢量输入输出,分散读,集中输入。 

       #include <sys/uio.h>

       ssize_t readv(int fd, const struct iovec *iov, int iovcnt);

       ssize_t writev(int fd, const struct iovec *iov, int iovcnt);

       ssize_t preadv(int fd, const struct iovec *iov, int iovcnt,
                      off_t offset);

       ssize_t pwritev(int fd, const struct iovec *iov, int iovcnt,
                       off_t offset);

    <5>truncate() and ftruncate()

    截断文件。

 

       #include <unistd.h>
       #include <sys/types.h>

       int truncate(const char *path, off_t length);
       int ftruncate(int fd, off_t length);

(3)文件描述符和打开文件之间的关系

    主要有三个表:进程级文件描述符表;系统级文件描述符表;文件系统的i-node表;

    进程级的有fd号,系统级的有offset,状态,inode指针,文件系统的有文件类型,文件锁等文件元信息;

  下面是书上的关系图:

并不是一一对应的,可以打开很多次。

(4)大文件IO

   32位架构中文件大小置于2GB的限制下面。大于其就是会出错EOVERFLOW。

   使用宏_FILE_OFFSET_BITS 64 就可以打开大文件。还有一种放法就是把带有offset参数的函数后面加64,如open64()。

(5)创建零时文件tmpfile

会有安全问题的函数是tmpnam(),tempnam(),mktemp().

安全的是tmpfile(),打开自带O_EXCL标志,防止之前所说的争抢的现象。

————————————————————finish

以上是关于TLPI(liunx/unix系统编程手册)笔记 深入探究文件I/O的主要内容,如果未能解决你的问题,请参考以下文章

TLPI(liunx/unix系统编程手册)笔记 深入探究文件I/O

TLPI读书笔记第63章:IO多路复用3

TLPI读书笔记第63章:IO多路复用4

TLPI读书笔记第51章-POSIX IPC介绍

《Linux系统编程手册》读书笔记——第2章基本概念

系统编程概念与文件属性