APUE学习笔记3_文件IO

Unix中的文件IO函数主要包括以下几个:open()、read()、write()、lseek()、close()等。这类I/O函数也被称为不带缓冲的I/O,标准I/O是带缓冲的I/O(当然,标准I/O也可以设置为不带缓冲)。

文件描述符

对于内核而言,所有打开的文件都通过文件描述符引用,比如read、write等操作都是通过文件描述符来实现的。文件描述符其实就是一个非负整数。当打开或者创建一个文件时,内核会向进程传递一个非负整数作为文件描述符,该文件描述符就可以作为参数传递给read、write等函数,进行文件操作。

UNIX系统中,通常是把0作为标准输入的描述符、1作为标准输出的描述符、2作为标准错误的描述符。

// <unistd.h> 

#define	STDIN_FILENO  0
#define STDOUT_FILENO 1
#define STDERR_FILENO 2

函数open()和openat()

#include <fcntl.h>

int open(const char *path, int oflag, ...);
int openat(int fd, const cahr *path, int oflag, ...);

使用open() 或者 openat() 函数打开或者创建文件。在函数open()中,path参数是文件的绝对路径或相对于当前文件的相对路径,oflag表示打开的方式。而在函数openat()中,path表示绝对路径(此时fd被忽略)或者是相对于fd的相对路径(fd 表示某已打开目录的文件描述符),openat()函数可以实现以相对路径来打开某些不便直接用相对路径表示的文件。

open和openat函数返回的文件描述符一定是最小的未使用描述符,比如一个应用程序可以先关闭标准输出(文件描述符是1),然后打开另一文件,这样该文件会返回1作为其文件描述符。

int fd1 = open("test/test.c", O_RDONLY);	//只读方式打开文件test.c,此处为相对路径。

int fd2 = open("test", O_RDONLY | O_DIRECTORY);	//打开当前目录下的文件夹test
int fd3 = openat(fd2, "test.c", O_RDONLY); //打开相对于test文件夹下的test.c

打开标志

文件打开标志有五个必选标志(必须指定一个且只能指定一个),与其他可选标志。

// 以下五个必须选一个且只能选一个

O_RDONLY // 只读打开
O_WRONLY // 只写打开
O_RDWR // 读写打开
O_EXEC // 只执行打开
O_SEARCH // 只搜索打开(应用于目录) // 以下为可选标志, O_APPEND // 每次写都追加到文件的结尾,文件以该标志打开时,如果使用lseek对文件重定位,若是读操作,重定位可以生效,若是写操作,重定位不生效,依然写在文件结尾。 O_CREAT // 若是文件爱你不存在则创建它,使用该标志时需要同时说明open第三个参数mode,即创建文件的权限。 O_TRUNC // 如果此文件存在且以只读或读写打开,则将文件长度截为0. O_DIRECTORY // 打开目录,若path不是目录则出错。

函数creat()

该函数只能以只写方式打开,我们可以直接使用open来实现创建新的文件,所以该函数就不用了。

函数close

#include <fcntl.h>

int close(int fd);

关闭一个文件时,还会释放加在该文件上的所有记录锁。

当一个进程结束时,内核会自动关闭它所有的打开文件,很多程序都用了这一点而不显示的调用close关闭打开文件。

函数lseek()

每个打开的文件都有一个与其相关的文件偏移量,表示从文件开始处到当前的字节数,通常是一个非负值。

#include <unistd.h>

off_t lseek(int fd, off_t offset, int whence);

// whence 可能取值如下
// SEEK_SET, 将文件的偏移量设置为距文件开始处offset个字节
// SEEK_CUR, 将文件的偏移量设置为距当前位置offset个字节(offset可正可负)
// SEEK_END, 将文件的偏移量设置为距结尾处offset个字节(offset可正可负)

通常,读写操作都是从当前文件偏移量处开始,并使偏移量增加所读写的字节数。根据系统默认情况,除非设置了O_APPEND,否则打开文件时,其偏移量被设置为0。

lseek若成功,则返回新的文件偏移量。文件的偏移量可以大于文件的长度,在这种情况下,对文件的下一次写操作将会增长改文件,并在文件中构成一个空洞。

文件空洞并不在磁盘占用存储区,读出的数据为0.

APUE学习笔记3_文件IO的更多相关文章

  1. 树莓派学习笔记——使用文件IO操作GPIO SysFs方式

    0 前言     本文描写叙述假设通过文件IO sysfs方式控制树莓派 GPIO端口.通过sysfs方式控制GPIO,先訪问/sys/class/gpio文件夹,向export文件写入GPIO编号, ...

  2. APUE学习笔记3——文件和目录

    1 简介 之前学习了执行I/O操作的基本函数,主要是围绕普通文件I/O的打开.读或写.下面继续学习Unix文件系统的其他特征和文件的基本性质.我们将从stat函数开始,了解stat结构所代表的文件属性 ...

  3. go语言学习笔记---读取文件io/ioutil 包

    io/ioutil 包几个函数方法 名称  作用 备注 ReadAll 读取数据,返回读到的字节 slice 1 ReadDir 读取一个目录,返回目录入口数组 []os.FileInfo, 2 Re ...

  4. APUE 学习笔记(三) 文件和目录

    1. 文件类型 文件类型信息包含在 struct stat 里的 st_mode 成员 (1)普通文件,unix内核并不区分文本文件和二进制文件 (2)目录文件,这种文件包含了其他文件的名字以及指向这 ...

  5. APUE 学习笔记(二) 文件I/O

    1. 文件I/O 对于内核而言,所有打开的文件都通过文件描述符引用,内核不区分文本文件和二进制文件 open函数:O_RDONLY  O_WRONLY  O_RDWR create函数: close函 ...

  6. APUE学习笔记2——文件I/O

    1 引言 本章首先讨论Unix系统中大多数文件I/O最常用的5个系统函数:open.read.write.lseek以及close. 本章所说明的函数又被成为不带缓冲的I/O,不带缓冲是指每个read ...

  7. SpringMVC:学习笔记(8)——文件上传

    SpringMVC--文件上传 说明: 文件上传的途径 文件上传主要有两种方式: 1.使用Apache Commons FileUpload元件. 2.利用Servlet3.0及其更高版本的内置支持. ...

  8. Linux系统学习笔记:文件I/O

    Linux支持C语言中的标准I/O函数,同时它还提供了一套SUS标准的I/O库函数.和标准I/O不同,UNIX的I/O函数是不带缓冲的,即每个读写都调用内核中的一个系统调用.本篇总结UNIX的I/O并 ...

  9. MySQL学习笔记-数据库文件

    数据库文件 MySQL主要文件类型有如下几种 参数文件:my.cnf--MySQL实例启动的时候在哪里可以找到数据库文件,并且指定某些初始化参数,这些参数定义了某种内存结构的大小等设置,还介绍了参数类 ...

随机推荐

  1. Notes 20180307 : 运算符

    我们前边曾说过程序=数据结构+算法,数据结构讲的是数据在内存中的存储形式,这个我会作为2018的一个重点来研究,不过在这里不做赘述,前半年的工作以JavaSE为主.算法则是我们在数据结构的基础上对其的 ...

  2. .Net core 使用SSH.Net上传到SFTP服务器和和下载文件

    今天换了个服务器,文件上传到sftp服务器上了,那么ftp和sftp服务器有什么区别呢,正常来说sftp会更安全一些. 废话不多说,首先.net core 上传到sftp需要引入一个Nuget包,就是 ...

  3. redis参数AOF参数的bug

    问题:redis 不想开启AOF了.但是还老是出现BGREWRITEAOF .(本redis版本为4.0.6) 涉及持久化参数设置如下: 排查及结果: 该redis以前开启过 AOF ,后来停止AOF ...

  4. 关于Hibernate基于version的乐观锁

    刚刚接触SSH框架,虽然可能这个框架已经比较过时了,但是个人认为,SSH作为一个成熟的框架,作为框架的入门还是可以的. 马马虎虎学完了Hibernate的基础,总结一点心得之类的. 学习Hiberna ...

  5. day 10 函数的进阶

    动态传参 (重点)  *    ** 形参  * args在形参位置, *表示不定参数--接受的是位置参数   接受到的位置参数的动态传参:  都是元组 形参的顺序: 位置  *args 默认值  * ...

  6. centos7安装mysql5.7.18笔记

    重装了一下系统,装了centos7,但是centos7下默认没有安装mysql,有MariaDB数据库,网上的解释是: “MariaDB数据库管理系统是MySQL的一个分支,主要由开源社区在维护,采用 ...

  7. Java学习笔记二十七:Java中的抽象类

    Java中的抽象类 一:Java抽象类: 在面向对象的概念中,所有的对象都是通过类来描绘的,但是反过来,并不是所有的类都是用来描绘对象的,如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就 ...

  8. 转载:C语言指针使用的注意事项

    相信大家对指针的用法已经很熟了,这里也不多说些定义性的东西了,只说一下指针使用中的注意事项吧. 一.在定义指针的时候注意连续声明多个指针时容易犯的错误,例如int * a,b;这种声明是声明了一个指向 ...

  9. Jenkins中Publish Over SSH插件使用

    Publish Over SSH插件安装 进入插件管理安装插件,我这里已经安装过了所以在installed里面,没安装过去available里面搜索. 系统设置中配置Publish Over SSH ...

  10. Go语言的数据类型

    1 概述 Go语言作为类C语言,支持常规的基础数据类型的的同时,支持常用的高级数据类型.他们是: 整数,int,uint,int8,uint8,int16,uint16,int32,uint32,in ...