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效率(比较随意):