Unix Programming :文件IO

文件描述符常量(unistd.h):

  • STDIN_FILENO
  • STDOUT_FILENO
  • STDERR_FILENO

通常这些常量分别对应于数字0,1,2

文件操作需要头文件 fcntl.h ,一些常量需要头文件unistd.h

  • open int open(const char *pathname, int oflag, ... ) 
    • 其中oflag可以是以下值的集合

      • O_RDONLY、O_WRONLY、O_RDWR 读写属性
      • O_APPEND、O_CREAT、O_EXCL、O_TRUNC、O_NOCTTY、O_NONBLOCK
  • creat 等效于 open (pathname, O_WRONLY | O_CREAT | O_TRUNC, mode);
  • closeint close(int filedes);
  • lseek off_t lseek(int filedes, off_t offset, int whence); 
    • 与偏移 offset 相对的位置whence:

      • SEEK_SET 文件起始
      • SEEK_CUR 当前位置
      • SEEK_END 文件末尾
  • write ssize_t write(int filedes, const void *buf, size_t nbytes); 

生成有洞的文件

使用lseek跳到文件原大小之外的范围然后写入数据,那么中间的部分数据不会被真正存储,不过读取是都当做0看待,但ls看到的文件大小还是将中间这些算进去的,这样可以非常快速的生成较大的空白文件。

 1 #include <stdio.h>
 2 #include <fcntl.h>
 3 #include <errno.h>
 4 #include <unistd.h>
 5 #include <limits.h>
 6 #include <string.h>
 7 
 8 char file_header[] = "this is the file header msg.";
 9 char file_end[] = "now we reach the file end.";
10 
11 int main() {
12     printf("size of off_t: %ld\n", sizeof(off_t));
13     printf("max file open number: %ld\n", sysconf(_SC_OPEN_MAX));
14     printf("max name length: %d\n", _POSIX_NAME_MAX);
15     printf("max path length: %d\n", _POSIX_PATH_MAX);
16 
17     int fd = open("tmpfile", O_RDWR | O_CREAT | O_TRUNC);
18 
19     if (fd < 0) {
20         perror("file operation open");
21         return 0;
22     }
23 
24     int head_len = strlen(file_header);
25     int end_len  = strlen(file_end);
26 
27     if (write(fd, file_header, head_len) != head_len) {
28         perror("write file header msg failed.");
29     }
30 
31     if (lseek(fd, 16384, SEEK_SET) == -1) {
32         perror("lseek failed.");
33     }
34 
35     if (write(fd, file_end, end_len) != end_len) {
36         perror("write file end msg failed.");
37     }
38 
39     if (close(fd) < 0) {
40         perror("file operation close");
41     }
42     return 0;
43 }

缓存影响I/O效率

由于有预读取的过程存在使用缓存可以提高复制速度,但是当缓存超过其预读取大小时缓存作用就降低了

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 #include <unistd.h>
 4 #include <fcntl.h>
 5 
 6 char buffer[16 * 1024];
 7 
 8 int main(int argc, char* argv[]) {
 9     if (argc < 2) {
10         fprintf(stderr, "usage:\n\t%s <buffer_size>\n", argv[0]);
11         return 0;
12     }
13 
14     int buffer_size = 0;
15     sscanf(argv[1], "%d", &buffer_size);
16 
17     if (buffer_size > sizeof(buffer)) {
18         fprintf(stderr, "buffer size too big. max: %ld\n", sizeof(buffer));
19         return 0;
20     }
21 
22     int bytes_read = 0;
23 
24     while ((bytes_read = read(STDIN_FILENO, buffer, buffer_size)) > 0) {
25         if (write(STDOUT_FILENO, buffer, bytes_read) != bytes_read) {
26             fprintf(stderr, "write error.\n");
27         }
28     }
29 
30     if (bytes_read < 0) {
31         fprintf(stderr, "read error.\n");
32     }
33 
34     return 0;
35 }

测试了使用不同缓存的情况下IO效率(比较随意):

Linux中的fd设备

posted @ 2014-04-11 21:38  卖程序的小歪  阅读(214)  评论(0编辑  收藏  举报