Unix环境高级编程——文件IO(一)

文件IO(一)


文件描述符(file descriptor)

Linux下一切是文件,当打开一个或创建一个文件时,内核向进程返回一个文件描述符,用来标识该文件。

unix将文件描述符0,1,2分别于标准输入、标准输出和标准错误关联。

unistd.h中是这么定义的

/* Standard file descriptors.  */
#define STDIN_FILENO    0       /* Standard input.  */
#define STDOUT_FILENO   1       /* Standard output.  */
#define STDERR_FILENO   2       /* Standard error output.  */


持有权限

文件自身有可读可写可执行权限(rwx),除此之外,也限制了进程持有文件这个行为本身的权限(只读、只写等)

/* open/fcntl.  */
#define O_RDONLY             00
#define O_WRONLY             01
#define O_RDWR               02

/* 以上三个选其一 */
/* 以下为可选项 */

#ifndef O_CREAT            /* 不存在则创建 */
# define O_CREAT           0100 /* Not fcntl.  */
#endif
#ifndef O_EXCL
# define O_EXCL            0200 /* Not fcntl.  */
#endif
#ifndef O_NOCTTY
# define O_NOCTTY          0400 /* Not fcntl.  */
#endif
#ifndef O_TRUNC           /* 如文件存在,且为O_WRONLY或O_RDWR成功打开,将其长度截断为0 */
# define O_TRUNC          01000 /* Not fcntl.  */
#endif
#ifndef O_APPEND          /* 写追加 */
# define O_APPEND         02000
#endif
#ifndef O_NONBLOCK
# define O_NONBLOCK       04000
#endif

#ifndef O_SYNC
# define O_SYNC        04010000
#endif


#ifdef __USE_XOPEN2K8
# define O_DIRECTORY    __O_DIRECTORY   /* Must be a directory.  */
# define O_NOFOLLOW     __O_NOFOLLOW    /* Do not follow links.  */
# define O_CLOEXEC      __O_CLOEXEC     /* Set close_on_exec.  */
#endif


打开、关闭、偏移函数

open
#include <fcntl.h>
int open(const char *path, int oflag, ...);
int openat(int fd, const char *path, int oflag, ...);

creat
#include <fcntl.h>
int creat(const char *path, mode_t mode);

close
#include <unistd.h>
int close(int fd);

lseek
#include <unistd.h>
off_t lseek(int fd, off_t offset, int whence);

//注:出错均返回-1

1.open 创建一个临时文件、先写该文件、然后又读该文件, 可以这样实现
open(path, O_RDWR | O_CREAT | O_TRUNC, mode);

2.creat 等效为:
open(path, O_WRONLY | O_CREAT | O_TRUNC, mode);
因此不再需要单独的creat函数。

3.close 关闭一个文件会释放该进程加在该文件上的所有记录锁。
此外,进程终止,内核会关闭它所有的打开文件。

4.lseek 文件读写都是从当前文件偏移量(current file offset)开始的,并使偏移量增加所读写的字节数
从unistd.h头文件中能找到如下定义

/* Values for the WHENCE argument to lseek.  */
#ifndef _STDIO_H                /* <stdio.h> has the same definitions.  */
# define SEEK_SET       0       /* Seek from beginning of file.  */
# define SEEK_CUR       1       /* Seek from current position.  */
# define SEEK_END       2       /* Seek from end of file.  */
#endif

常用如下方式确定打开文件的当前偏移量
lseek(fd, 0, SEEK_CUR);

如果文件描述符指向的是一个管道、FIFO、网络套接字,则返回-1

    if (-1 == lseek(STDIN_FILENO, 0, SEEK_CUR))
        printf("cannot seek\n");
    else
        printf("seek OK\n");

    exit(0);

在这里插入图片描述


那么重点来了!

读写函数

read
#include <unistd.h>
ssize_t read(int fd, void *buf, size_t nbytes);

write
#include <unistd.h>
ssize_t write(int fd, const void *buf, size_t nbytes); 

//注:出错均返回-1

拿书上给的例子测试一下,从标准输入读取,写到标准输出里

#include "apue.h"

#define BUFFSIZE 4096

int main()
{
    int n;
    char buf[BUFFSIZE];

    while ((n = read(STDIN_FILENO, buf, BUFFSIZE)) > 0)
        if (n != write(STDOUT_FILENO, buf, n))
            err_sys("write error");

    if (n < 0)
        err_sys("read error");

    exit(0);
}

在这里插入图片描述


上面是常用的文件IO函数,不带缓冲的IO(unbuffered I/O),实际上使用了内核中的系统调用

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值