【UNIX环境高级编程】文件 IO 操作 一 ( open | close | creat | lseek | write | read )
博客地址 : http://blog.csdn.net/shulianghan/article/details/46980271
一. 文件打开关闭操作相关函数介绍
1. open 函数
(1) open 函数简介
open 函数解析 :
-- 函数定义 :
#include <fcntl.h> int open(const char *path, int oflag, ...);
-- 函数作用 : 打开或者创建一个文件;
-- 返回值 : 打开文件成功, 返回文件描述符; 如果失败, 返回 -1; 返回的文件描述符是最小的未用描述符值
(2) open 函数参数简介
参数解析 :
-- const char *path : 要打开或者创建的文件名;
-- int oflag : 函数选项, 可以是多个常量进行 "或" 运算;
-- 第三参数 : 对于打开文件来说是用不到第三参数的, 如果需要创建文件, 则需要指定第三参数;
int oflag 参数必选常量解析 : 下面的三个常量必须只能且只能指定一个;
-- O_RDONLY : 打开的文件只能读取, 没有写权限;
-- O_WRONLY : 打开的文件只能写入, 没有读权限;
-- O_RDWR : 打开的文件既能读取, 也能写入, 有双权限;
int oflag 参数可选常量解析 :
-- O_APPEND : 每次写入都追加到文件末尾;
-- O_CREATE : 如果文件不存在, 就创建, 如果有这个参数, 就需要使用第三个参数来指定创建文件时的参数;
-- O_EXCL : 指定该参数, 同时指定 O_CREATE, 文件如果存在就会报错;
-- O_TRUNC : 如果文件存在, 并且有写权限的前提下, 打开时会将其内容清空, 从新写入;
-- O_NOCTTY : 如果第一个参数文件路径指向一个终端设备, 不能将该设备作为进程的控制终端;
-- O_NONBLOCK : 如果文件路径指向一个 FIFO, 特殊文件块, 字符特殊文件, 同时指定该选项, 文件的IO操作设置为非阻塞模式;
int oflag 同步参数可选常量解析 :
-- O_DSYNC : 每次 write 操作之前等待 IO 完成, 如果写操作不影响读取刚写入的数据, 则不等待文件属性被更新;
-- O_RSYNC : 读操作时等待, 直到所有的写操作都完成;
-- O_SYNC : 每次写都要等待物理 IO 操作完成, 包括 write 引起的文件属性更新; 即 数据和属性同步更新;
2. create 函数
(1) create 函数简介
create 函数简介 :
-- 函数定义 :
#include <fcntl.h> int creat(const char *path, mode_t mode);
-- 返回值 : 返回只写打开的文件描述符, 出错返回 -1;
-- 等效函数 : open(path_name, O_WRONLY | O_CREATE | O_TRUNC, mode);
-- mode_t mode 参数 : 指定文件的所有者;
(2) create 函数局限性
create 局限性 :
-- 只写 : create 函数只能以只写方式打开创建的文件;
-- 读取新文件方法 : 先 create 创建只写文件, 再调用 close 函数, 再调用 open 方法打开文件读取文件;
-- 创建只读文件 : open(path_name, O_RDWR | O_CREATE | O_TRUNC, mode);
3. close 函数
函数简介 :
-- 函数定义 :
#include <unistd.h> int close(int fildes);
-- 作用 : 关闭文件, 并释放 进程 加在该文件上得所有 记录锁;
-- 关于进程 : 进程终止时, 内核会自动关闭该进程中打开的所有文件, 很多情况下都会使用关闭进程隐式关闭文件;
二. 文件偏移操作相关函数介绍
1. lseek 函数
(1) lseek 函数简介
lseek 函数简介 :
-- 函数定义 :
#include <unistd.h> off_t lseek(int fildes, off_t offset, int whence);
-- 作用 : 显式的为一个打开的文件设置偏移量;
-- 返回值 : 如果设置偏移量成功, 返回新的偏移量;
(2) 文件偏移量简介
文件偏移量 :
-- 当前文件偏移量 : 每个打开的文件都有一个当前文件偏移量, 非负整数, 从开始处计算的字节数; 读写操作都是从当前文件偏移处开始, 读写会使当前文件偏移量增加 读写的字节数;
-- 默认偏移量 : 打开一个文件时默认 当前文件偏移量 是0, 除非指定 O_APPEND 选项;
-- 偏移量的值 : 普通文件偏移量必须是非负整数; 对于某些设备文件允许存在负数偏移量, 因此判断是否可 lseek 时, 要判断返回的文件偏移量是否 == -1;
(3) int where 参数简介
where 参数简介 :
-- SEEK_SET : 将文件偏移量设置为 0 + offset;
-- SEEK_CUR : 将文件偏移量设置为 当前位移 + offset;
-- SEEK_END : 将文件偏移量设置为 文件长度 + offset;
(4) lseek 源码示例
源码示例 :
/************************************************************************* > File Name: fun_lseek.c > Author: octopus > Mail: octopus_truth.163.com > Created Time: 三 7/22 07:46:59 2015 ************************************************************************/ #include<stdio.h> #include<unistd.h> #include<stdlib.h> int main(int argc, char * argv[]) { /* * 设置标准输入文件的 "当前文件偏移量", * 设置为当前的位置 + 0; */ if(lseek(STDIN_FILENO, 0, SEEK_CUR) == -1) printf("lseek 结果 -1, 该文件不能lseek\n"); else printf("该文件可以执行 lseek 方法\n"); exit(0); }
编译执行 :
localhost:file octopus$ gcc fun_lseek.c localhost:file octopus$ ./a.out 该文件可以执行 lseek 方法
(5) 文件空洞
文件空洞形成 :
-- 文件偏移量作用 : 文件偏移量是记录在内核中, 不引起 IO 操作, 这个偏移量主要用于执行下一次的 IO 操作;
-- 空洞形成 : 如果文件偏移量大于当前文件长度, 下一次写操作会直接加长文件, 并在中间形成一个 "文件空洞";
-- 磁盘占用情况 : 文件空洞是不占用磁盘存储区的, 写入数据超出文件长度时, 新写入的数据会重新分配磁盘块, 之间的一段文件空洞不会占用磁盘空间;
二. 文件读写操作相关函数介绍
1. read 函数
函数简介 :
-- 函数内容 :
#include <sys/types.h> #include <sys/uio.h> #include <unistd.h> ssize_t read(int fildes, void *buf, size_t nbyte);
-- 作用 : 从 fildes 代表的文件中, 读取 nbyte 个函数到 buf 缓冲区中, 读取到得字节数可能少于 nbyte;
-- 返回值 : 如果 read 操作成功, 返回读取到得字节数, 如果失败, 返回 -1;
2. write 函数
函数简介 :
-- 函数内容 :
#include <unistd.h> ssize_t write(int fildes, const void *buf, size_t nbyte);
-- 函数作用 : 将 buf 字符串的前 nbyte 个字节数据写入 files 文件标示符 代表的文件中;
-- 返回值 : 若成功, 返回已写的字节数, 如果失败返回 -1;
3. write read 函数示例
源码示例 :
-- 源码 :
/************************************************************************* > File Name: fun_read_write.c > Author: Han Shuliang > Mail: octopus_truth@163.com > Created Time: 五 7/29 15:00:18 2016 ************************************************************************/ #include <stdio.h> #include <unistd.h> #define SIZE 1024 int main(int argc, char * argv[]) { int n; char buf[SIZE]; //读取标准输入流中的数据到 buf 字节数组中 while ((n = read(STDIN_FILENO, buf, SIZE)) > 0) //将 buf 字节数组中的数据写出到 标准输出流中 if(write(STDOUT_FILENO, buf, n)!= n) printf("写出内容出错"); if(n < 0) printf("读取过程出错"); return 0; }
-- 执行结果 :
bogon:file octopus$ gcc fun_read_write.c bogon:file octopus$ ./a.out Han Shuliang Han Shuliang CSDN CSDN ^C bogon:file octopus$
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 octopus-2:file octopus$ ls a.out file_read_write.file fun_lseek.c fun_lseek_hole.c fun_read_write.c octopus-2:file octopus$
【UNIX环境高级编程】文件 IO 操作 一 ( open | close | creat | lseek | write | read )的更多相关文章
- UNIX环境高级编程——文件I/O
一.文件描述符 对于Linux而言,所有对设备或文件的操作都是通过文件描述符进行的.当打开或者创建一个文件的时候,内核向进程返回一个文件描述符(非负整数).后续对文件的操作只需通过该文件描述符,内核记 ...
- UNIX 环境高级编程 文件和目录
函数stat , fstat , fstatat , lstat stat函数返回与此文件有关的信息结构. fstat函数使用已打开的文件描述符(而stat则使用文件名) fstatat函数 为一个相 ...
- UNIX环境高级编程 文件I/O
大多数文件I/O 只需要用到 5个函数 : open , read , write , lseek , close 本章描述的都是不带缓冲的I/O(read write 都调用内核中的一个系统调 ...
- UNIX环境高级编程 标准IO库
标准I/O库处理很多细节,使得便于用户使用. 流和 FILE 对象 对于标准I/O库,操作是围绕 流(stream)进行的.当用标准I/O打开或创建一个文件时,我们已使一个流与一个文件相关联. 对于A ...
- UNIX环境高级编程——文件和目录
一.获取文件/目录的属性信息 int stat(const char *path, struct stat *buf); int fstat(int fd, struct stat *buf); in ...
- UNIX环境高级编程---标准I/O库
前言:我想大家学习C语言接触过的第一个函数应该是printf,但是我们真正理解它了吗?最近看Linux以及网络编程这块,我觉得I/O这块很难理解.以前从来没认识到Unix I/O和C标准库I/O函数压 ...
- (二) 一起学 Unix 环境高级编程 (APUE) 之 文件 IO
. . . . . 目录 (一) 一起学 Unix 环境高级编程 (APUE) 之 标准IO (二) 一起学 Unix 环境高级编程 (APUE) 之 文件 IO (三) 一起学 Unix 环境高级编 ...
- Unix环境高级编程:文件 IO 原子性 与 状态 共享
参考 UnixUnix环境高级编程 第三章 文件IO 偏移共享 单进程单文件描述符 在只有一个进程时,打开一个文件,对该文件描述符进行写入操作后,后续的写入操作会在原来偏移的基础上进行,这样就可以实现 ...
- (一) 一起学 Unix 环境高级编程 (APUE) 之 标准IO
. . . . . 目录 (一) 一起学 Unix 环境高级编程 (APUE) 之 标准IO (二) 一起学 Unix 环境高级编程 (APUE) 之 文件 IO (三) 一起学 Unix 环境高级编 ...
随机推荐
- .Net及C#基础知识,面试宝典
作为你一.Net和C#开发这些知识,你是否掌握了,你是否算的上一名入门的程序员? 技术不行并不可怕,可怕的是你不知道自己还需做哪一方面的提升,本篇文字本人的一些面试时所经常涉及的问题,并且在网上收集了 ...
- VMWare - Ubuntu 64 (16.04)之扩容介绍
背景 貌似是一个老生常谈的问题哈,由于自己之前也没有弄过,今天正好有时间稍微折腾了一下. 这里就选择最简单的方式来为大家呈现. VMWare 的设置 没有什么可以过多说的,完全是图形操作.这里直接上图 ...
- 多线程join(加入)
package cn.itcast.thread;/* join方法. 加入 */ //老妈class Mon extends Thread{ public void run() { System.o ...
- 算法二叉搜索树之AVL树
最近学习了二叉搜索树中的AVL树,特在此写一篇博客小结. 1.引言 对于二叉搜索树而言,其插入查找删除等性能直接和树的高度有关,因此我们发明了平衡二叉搜索树.在计算机科学中,AVL树是最先发明的自平衡 ...
- Noip2017 普及 T3 Chess
神奇的场上原码 #include<iostream> #include<cstdio> #include<cstring> #include<queue> ...
- JavaScript 函数定义
JavaScript 使用关键字 function 定义函数. 函数可以通过声明定义,也可以是一个表达式. 函数声明 在之前的教程中,你已经了解了函数声明的语法 : function function ...
- 导出和导入Docker容器
导出容器 如果要导出本地某个容器,可以使用 docker export 命令. $ sudo docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATU ...
- Java web文件上传下载
[版权申明:本文系作者原创,转载请注明出处] 文章出处:http://blog.csdn.net/sdksdk0/article/details/52048666 作者:朱培 ID:sdksdk0 邮 ...
- 常用的DDL语句
create database mydb1; 创建一个名称为mydb1的数据库. use db_name; 切换数据库 ; show databases; 查看所有的数据库: select datab ...
- Web自动化框架LazyUI使用手册(3)--单个xpath抓取插件详解(selenium元素抓取,有此插件,便再无所求!)
概述 前面的一篇博文粗略介绍了基于lazyUI的第一个demo,本文将详细描述此工具的设计和使用. 元素获取插件:LazyUI Elements Extractor,作为Chrome插件,用于抓取页面 ...