APUE Reading Notes------Chapter 3

Chapter 3. File I/O

 

3.2 File Descriptors

The magic numbers 0, 1, 2 should be replaced in POSIX-compliant applications with the symbplic constants STDIN_FILENO, STDOUT_FILENO, and STDERR_FILENO.These contants are defined in the <unistd.h> header.

3.3 open Function

    A file is opened or created by calling the open function.

    #include <fcntl.h>

int open(const char *pathname, into flag,…/* mode_t mode */);

Returns: file descriptor if OK, -1 on error.

 

oflag argument: This argument is formed by ORing together one or more of the following constants from the <fcntl.h> header:

O_RDONLY Open for reading only.

O_WRONLY Open for writing only

O_RDWR Open for reading and writing.

   

    One and only one of these three constants must be specified. The following constants are optional:

O_APPEND O_CREAT O_EXCL O_TRUNC O_NOCTTY O_NONBLOCK

 

The following three flags are also optional. They are part of the synchronized and output option of the Single UNIX Specification:

O_DSYNC O_RSYNC O_SYNC

 

3.4 creat Function

A new file can also be created by calling the creat function.

    #include <fcntl.h>

    int creat(const char *pathname, mode_t mode);

    Returns: file descriptor opened for write-only if OK, -1 on error.

    NOTE: Write-only way, if file exists truncate to 0

 

3.5 close Function

    An open file is closed by calling the close function.

    #include <unistd.h>

    int close(int filedes);

    Returns: 0 if OK, -1 on error.

    When a process terminates, all of its open files are closed automatically by the kernel.

 

3.6 lseek Function

    Every open file has an associated “current file offset”, normally a non-negative integer that measures the number of bytes from the beginning of the file.

    An open file’s offset can be set explicitly by calling lseek.

    #include <unistd.h>

    off_t lseek(int filedes, off_t offset, int whence);

    Returns: new file offset if OK, -1 on error.

    The interpretation of the offset depends on the value of the whence argument.

    If whence is SEEK_SET, the file’s offset is set to offset bytes from the beginning of the file.

    If whence is SEEK_CUR, the file’s offset is set to its current value plus the offset. The offset can be positive or negative.

    If whence is SEEK_END, the file’s offset is set to the size of file plus the offset. The offset can be positive or negative.

 

    Because negative offsets are possible, we should be careful to compare the return value from lseek as being equal to or not equal to -1 and not test if it’s less than 0.

 

    The file’s offset can be greater than the file’s current size, in which the next write to the file will extend the file. This is referred to as creating a hole in a file and is allowed. Any bytes in a file that have not been written are read back as 0.

 

    A hole in a file isn’t required to have storage backing it on disk. Depending on the file system implementation, when you write after seeking past the end of the file, new disk blocks might be allocated to store the data, but there is no need to allocate disk blocks for the data between the old end of file and the location where you start writing.

 

3.7 read Function

    Data is read from an open file with the read function.

    #include <unistd.h>

    ssize_t read(int filedes, void *buf, size_t nbytes);

    Returns: number of bytes read, 0 if end of file, -1 on error.

 

3.8 write Function

    Data is written to an open file with the write function.

    #include <unistd.h>

    ssize_t write(int filedes, const void *buf, size_t nbytes);

    Returns: number of bytes written if OK, -1 on error.

 

3.10 File Sharing

    The UNIX System supports the sharing of open files among different processes.

    The kernel uses three data structures to represent an open file, and the relationships among them determine the effect one process has on another with regard to file sharing.

1.  Every process has an entry in  the process table. Within each process table entry is a table of open file descriptors, which we can think of as a vector, with one entry per descriptor. Associated with each file descriptor are

a.  The file descriptor flags

b.  A pointer to a file table entry

2.  The kernel maintains a file table for all open files. Each file table entry contains

a.  The file status flags for the file.

b.  The current file offset

c.  A pointer to the v-node table entry for the file

3.  Each open file has a v-node structure that contains information about the type of file and pointers to functions that operate on the file.

kernelstructure.bmp

twoprosonefile.bmp

 

3.11 Atomic Operations

pread and pwrite Functions

The Single UNIX Specification includes XSI extensions that allow applications to seek and perform I/O atomically, These extensions are pread and pwrite.

#include <unistd.h>

ssize_t pread(int filedes, void *buf, size_t nbytes, off_t offset);

    Returns: number of bytes read, 0 if end of file, -1 if on error.

 

    ssize_t pwrite(int filedes, const void *buf, size_t nbytes, off_t offset);

    Returns: number of bytes written if OK, -1 on error.

 

    Calling pread is equivalent to calling lseek followed by a call to read, with the following exceptions.

    There is no way to interrupt the two operations using pread.

    There file pointer is not updated.

    Calling pwrite is equivalent to calling lseek followed by a call to write, with similar exceptions.

 

    In general, the term atomic operation refers to an operation that might be composed of multiple steps. If the operation is performed atomically, either all the steps are performed, or none are performed. It must not be possible for a subset of the steps to be performed.

   

3.12 dup and dup2 Functions

    An existing file descriptor is duplicated by either of the following functions.

    #include <unistd.h>

    int dup(int filedes);

    int dup2(int filedes, int filedes2);

    Both returns: new file descriptor if OK, -1 on error.

    The new file descriptor returned by dup is guaranteed to be the lowest-numbered available file descriptor. With dup2, we specify the value of the new descriptor with the filedes2 argument. If filedes2 is already open, it is first closed. If filedes equals filedes2, then dup2 returns filedes without closing it.

 

3.13 sync, fsync, and fdatasync Functions

    To ensure consistency of the file system on disk with the contents of the buffer cache, the sync, fsync, and fdatasync functions are provided.

    #include <unistd.h>

    int fsync(int filedes);

    int fdatasync(int filedes);

    Returns: 0 if OK, -1 on error.

 

    void sync(void);

   

    The sync function simply queues all the modified block buffers for writing and returns; it does not wait for the disk writes to take place. The function sync is normally called periodically from a system daemon.

    The function fsync refers only to a single file, specified by the file descriptor filedes, and waits for the disk writes to complete before returning.

    The fdatasync function is similar to fsync, but it affects only the data portions of a file. With fsync, the file’s attributes are also updated synchronously.

 

3.15 fcntl Function

    The fcntl function can change the properties of a file that is already open.

    #include <fcntl.h>

    int fcntl(int filedes, int cmd, …/* int arg */);

    Returns: depends on cmd if OK, -1 on error.

 

    The fcntl function is used for five defferent purposes.

1.  Duplicate an existing descriptor(cmd = F_DUPFD)

2.  Get/set file descriptor flags(cmd = F_GETFD or F_SETFD)

3.  Get/set file status flags(cmd = F_GETFL or F_SETFL)

4.  Get/set asynchronous I/O ownership(cmd = F_GETTOWN or F_SETOWN)

5.  Get/set record locks(cmd = F_GETLK, F_SETLK, or F_SETLKW)

3.16 ioctl Function

    The ioctl function has always been the catchall for I/O operations. Anything that couldn’t be expressed using one of the other functions in this chapter usually ended up being specified with an ioctl.

    #include <unistd.h> /* System V */

    #include <sys/ioctl.h> /* BSD and Linux */

    #include <stropts.h> /* XSI STREAMS */

 

    int ioctl(int filedes, int request, …);

    Returns: -1 on error, something else if OK.

 

3.16 /dev/fd

    Newer system provide a directory named /dev/fd whose entries are files named 0, 1, 2, and so on. Opening the file /dev/fd/n is equivalent to duplicating descriptor n, assuming that descriptor n is open.

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值