1. 程式人生 > >Unix環境高級編程(一)文件I/O

Unix環境高級編程(一)文件I/O

argc 緩沖 png body 定位 creat desc printf tde

  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\n");
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\n");
19         exit(1);
20     }
21     printf("Open file successfully.\n");
22     printf("Input a string: ");
23     gets(buf);
24    //寫入文件
25     write(fd,buf,strlen(buf));
26     close(fd);
27     printf("Open file to read.\n");
28      if((fd = open(filename, O_RDONLY)) == -1)
29     {
30         perror("Cannot open file\n");
31         exit(1);
32     }
33     //從文件中讀取
34     read(fd,buf,100);
35     printf("Read from file is: %s\n",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#>\n");
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.\n");
26         break;
27     case O_WRONLY:
28         printf("write only\n");
29         break;
30     case O_RDWR:
31         printf("read write.\n");
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(\n);
41     return 0;
42 }
技術分享圖片

程序測試結果如下:

技術分享圖片

Unix環境高級編程(一)文件I/O