4. 函数综合示例
/************************************************************************* > File Name: fun_read.c > Author: octopus > Mail: octopus_truth.163.com > Created Time: 一 7/27 07:09:36 2015 ************************************************************************/ #include <stdio.h> #include <sys/types.h> // ... read() 头文件 #include <sys/uio.h> // ... read() 头文件 #include <unistd.h> // ... read() write() 函数头文件 #include <stdarg.h> // va_list 可变参数操作头文件 #include <string.h> // strlen strcat 方法的头文件 #include <errno.h> // errno 的头文件 #include <stdlib.h> // exit() 方法的头文件 #include <fcntl.h> // open() 函数的头文件 #define MAXLINE 4096 #define MAXWORD 20 void err_sys(const char *fmt, ...); int main(int argc, char * argv[]) { char *buf = "abcdefg\n"; char buf_read[MAXWORD]; int fd; int creat_result; int write_size; int close_result; int read_size; //创建一个文件, 使用打开方式, 如果文件不存在, 就重创建并打开 if( ( fd = open("file_read_write.file", O_WRONLY | O_CREAT | O_TRUNC) ) == -1) err_sys("创建文件出错"); //向文件中写出数据 if( (write_size = write(fd, buf, strlen(buf))) == -1) err_sys("向文件写出数据出错"); if( (close_result = close(fd)) == -1) err_sys("关闭文件出错"); if( (fd = open("file_read_write.file", O_RDONLY)) == -1) err_sys("打开文件出错"); //从文件中读取文件内容 if( (read_size = read(fd, buf_read, strlen(buf)) ) == -1) err_sys("读取文件出错"); if( (close_result = close(fd)) == -1) err_sys("关闭文件出错"); printf("文件中得内容 : %s \n", buf_read); } static void err_doit(int errnoflag, int error, const char* fmt, va_list ap) { char buf[MAXLINE]; //将 ap 可变参数使用 fmt 格式, 放置 MAXLINE 个字符到 buf 缓冲中 vsnprintf(buf, MAXLINE, fmt, ap); /* * 如果需要错误信息, 根据错误号获取标准错误信息, 将该信息添加到 buf 缓冲中 * strlen 作用 : 获取字符串长度 * strerror 作用 : 根据错误号获取错误信息 */ if(errnoflag) snprintf(buf + strlen(buf), MAXLINE - strlen(buf), ": %s", strerror(errno)); //在 buf 字符串后添加换行符号 strcat(buf, "\n"); //刷新标准输出流 fflush(stdout); //将标准错误输出添加到 buf 缓冲区中 fputs(buf, stderr); //刷新所有缓冲区 fflush(NULL); } void err_sys(const char *fmt, ...) { va_list ap; va_start(ap, fmt); err_doit(1, errno, fmt, ap); va_end(ap); exit(0); }
执行结果 :
octopus-2:file octopus$ ls fun_lseek.c fun_lseek_hole.c fun_read_write.c octopus-2:file octopus$ gcc fun_read_write.c octopus-2:file octopus$ sudo ./a.out Password:
文件中得内容 : abcdefg
四. 文件读写原子操作相关函数介绍
1. pread 函数
pread 函数 :
-- 1. 函数内容 :
#include <unistd.h> ssize_t pread(int fd, void *buf, size_t count, off_t offset);
-- 2. 函数作用 : 读取文件描述符 fd 对应的文件, 返回读取到的文件字节个数, 读取到文件结尾 返回 0, 出现错误返回 -1;
-- 3. 函数返回值 : 返回读取文件的字节数, 读取到结尾返回 0, 出错返回 -1;
pread 与 read 方法作用 :
-- 1. 等价执行流程 : pread 方法等价于 先调用 lseek 方法, 再调用 read 方法;
-- 2. 与等价流程的区别 : ① 执行 pread 方法时, 先定位 后 读取 的两个操作, 不能中断; ② 文件指针 不更新;
2. pwrite 函数
pwrite 函数 :
-- 1. 函数内容 :
#include <unistd.h> ssize_t pwrite(int fd, const void *buf, size_t count, off_t offset);
-- 2. 函数作用 : 写出数据到指定的位置;
-- 3. 函数返回值 : 返回写出的字节数, 出现错误返回 -1;
-- 4. 等价操作 : pwrite 等价于 lseek 和 write 操作;
3. pread 和 pwrite 函数示例
函数示例过程 :
-- 1. 打开文件, 如果没有就创建;
-- 2. 写出 a ~ z 26个子母;
-- 3. 读取文件 10 ~ 15 个字节;
-- 4. 向第 10 个字节处写出 "00000" 字符串;
函数示例 :
-- 代码 :
#include <stdio.h> #include <fcntl.h> #include <unistd.h> #include <string.h> int main(int argc, char **argv) { printf("main : \n"); int file_fd, write_result; char * buffer = "abcdefghigklmnopqrstuvwxyz"; file_fd = open("5.pread_write.txt", O_RDWR | O_APPEND | O_CREAT); printf("file_fd = %d\n", file_fd); write_result = write(file_fd, buffer, strlen(buffer)); printf("write success, count = %d\n", write_result); return 0; }
.