• Unix环境高级编程(一)文件I/O


      Unix系统中大多数文件I/O只需用到五个函数:open、read、write、lseek、close。本章说介绍的I/O是不带缓冲的,即:每个read和write都调用内核中的一个系统调用。不是ISO C的组成部分。对于内核而言,所有打开的文件都通过文件描述符引用。

    在<unistd.h>中定义三个标准的文件描述符:

    STDIN_FILENO   标准输入

    STDOUT_FILENO  标准输出

    STDERR_FILENO  标准出错输出

    具体函数描述:在<fcntl.h>头文件下

    int open(const char *path, int oflag, ... );  //打开或者创建一个文件
    int creat(const char *path, mode_t mode); //创建一个文件
    int close(int fildes);//关闭一个打开的文件
    off_t lseek(int fildes, off_t offset, int whence);  //为打开的文件设置偏移量
    ssize_t read(int fd, void *buf, size_t count);
    ssize_t write(int fildes, const void *buf, size_t nbyte);

    复制代码
     1 #include <stdio.h>
     2 #include <stdlib.h>
     3 #include <string.h>
     4 #include <unistd.h>
     5 #include <fcntl.h>
     6 #include <errno.h>
     7 
     8 int main()
     9 {
    10     char *filename = ".//file";
    11     char buf[100];
    12     int fd;
    13     memset(buf,0,100);
    14     printf("Open file to write
    ");
    15     //打开文件,不存在和新建
    16     if((fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC,S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)) == -1)
    17     {
    18         perror("Cannot open file
    ");
    19         exit(1);
    20     }
    21     printf("Open file successfully.
    ");
    22     printf("Input a string: ");
    23     gets(buf);
    24    //写入文件
    25     write(fd,buf,strlen(buf));
    26     close(fd);
    27     printf("Open file to read.
    ");
    28      if((fd = open(filename, O_RDONLY)) == -1)
    29     {
    30         perror("Cannot open file
    ");
    31         exit(1);
    32     }
    33     //从文件中读取
    34     read(fd,buf,100);
    35     printf("Read from file is: %s
    ",buf);
    36     close(fd);
    37     return 0;
    38 }
    复制代码

    程序测试结果如下:

    复制一个现有的文件描述符函数
    int dup(int fildes);
    int dup2(int fildes, int fildes2);
    dup返回的新文件描述符是当前可用文件描述符中最小值,dup2则是用fildes2参数指定新文件描述符的数值,若fildes2打开则关闭,若fildes等于fildes2则不关闭,返回fildes2.在CGI程序用dup2将文件描述符重新定位到标准输入和标准输出。即:dup2(fd,STDOUT_FILENO)或dup2(fd,STDIN_FILENO)。

    改变已打开文件的性质函数:
    int fcntl(int fd, int cmd, ... /* arg */ );
    函数功能:
    复制一个现有的描述符(cmd=F_DUPFD)
    获得或设置文件描述符(cmd=F_GETFD|F_SETFD)
    获得或设置文件状态标志(cmd=F_GETFL|F_SETFL)
    获得或设置异步I/O所有权(cmd=F_GETOWN|F_SETOWN)
    获得或设置记录锁(cmd=F_GETLK|F_SETLK、F_SETLKW)

    可以用fcntl函数设置文件状态,常用设置套接字描述符为非阻塞O_NONBLOCK

    下面写个程序完成打印出指定文件描述符的文件状态标志。程序如下:

    复制代码
     1 #include <stdio.h>
     2 #include <string.h>
     3 #include <unistd.h>
     4 #include <fcntl.h>
     5 #include <errno.h>
     6 #include <stdlib.h>
     7 
     8 int main(int argc,char* argv[])
     9 {
    10    int val;
    11    if(argc != 2)
    12    {
    13       printf("usage: <descriptor#>
    ");
    14       exit(-1);
    15    }
    16    val = fcntl(atoi(argv[1]),F_GETFL,0);
    17    if(val == -1)
    18    {
    19       perror("fcntl() error");
    20       exit(-1);
    21    }
    22    switch(val & O_ACCMODE)
    23    {
    24     case O_RDONLY:
    25         printf("read only.
    ");
    26         break;
    27     case O_WRONLY:
    28         printf("write only
    ");
    29         break;
    30     case O_RDWR:
    31         printf("read write.
    ");
    32         break;
    33     default:
    34         printf("unknown access mode");
    35    }
    36    if(val&O_APPEND)
    37      printf(",append");
    38    if(val&O_NONBLOCK)
    39      printf(",nonblocking");
    40     putchar('
    ');
    41     return 0;
    42 }
    复制代码

    程序测试结果如下:

  • 相关阅读:
    LINQ查询操作符之First、FirstOrDefault、Last、LastOrDefault、ElementAt、ElementAtOrDefault、Contains、Any、All、Coun
    .Net 使用的快捷键
    P2073 送花
    洛谷P1514 引水入城
    花园
    八数码难题
    并查集题目整理
    树链剖分(强势借鉴)
    模拟题
    考试整理
  • 原文地址:https://www.cnblogs.com/alantu2018/p/8465951.html
Copyright © 2020-2023  润新知