【APUE】文件 I/O 操作(一)

本文涉及的产品
云解析 DNS,旗舰版 1个月
全局流量管理 GTM,标准版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介: 【APUE】文件 I/O 操作(一)

一. 文件打开关闭操作相关函数介绍




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$



目录
相关文章
|
6月前
|
算法 Linux C++
【Linux系统编程】Linux目录操作:opendir、readdir与closedir详解
【Linux系统编程】Linux目录操作:opendir、readdir与closedir详解
341 0
|
6月前
|
存储 Linux
Linux文件编程(lseek函数和stat函数)
Linux文件编程(lseek函数和stat函数)
102 0
Linux文件编程(lseek函数和stat函数)
【APUE】文件 I/O 操作(二)
【APUE】文件 I/O 操作(二)
113 0
|
缓存 安全 测试技术
APUE-文件和目录(六)函数ftw和nftw
名字 ftw,nftw - 文件树遍历 概要 #include int nftw(const char *dirpath, int (*fn) (const char *fpath, const struct stat *sb,int typeflag, struct FTW *f...
1311 0
|
机器学习/深度学习 Unix Shell
APUE-文件和目录(八)文件时间
文件的时间 与文件相关的三个时间值: 访问时间:最后一次访问文件的时间。例如,cat命令会修改这个时间。 修改时间:文件内容最后一次被修改的时间。 状态更改时间:文件的i节点最后一次被修改的时间。例如,更改文件的访问权限、更改用户ID、更改链接数都会修改i节点。
971 0
|
云计算
APUE-文件和目录(五)函数rename和renameat
rename和renameat #include int rename(const char *oldname,const char*newname); int renameat(int oldfd,const char *oldname,int newfd, const char *newnam...
918 0
|
安全 Unix Linux
APUE-文件和目录(七)符号链接
符号链接 符号链接的用途 符号链接是对一个文件的间接指针,它与前面介绍的硬连接不同,硬连接指向文件的i节点。引入符号链接是为了避开硬连接的一些限制: 硬链接通常要求链接和文件位于同一文件系统中。 只有超级用户才能创建指向目录的硬链接(在底层文件系统支持的情况下)。
918 0
|
Unix Linux 数据库
APUE-文件和目录(四)文件系统
一个命令 mkfs 讲文件系统前先介绍一个用于创建文件系统的命令: mkfs mkfs [options] [-t type fs-options] device [size] 描述 mkfs用来在设备上创建一个Linux文件系统,这个设备通常情况下是一个硬盘分区。
985 0