Linux中文件I/O函数

一、lseek函数

每个打开文件都有一个与其相关联的“当前文件偏移量”。它通常是一个非负整数,用以度量从文件开始处

计算的字节数。通常,读、写操作都从当前文件偏移量处开始,并使偏移量增加所读写的字节数。当打开一个文

件时,除非指定O_APPEND选项(调用open函数时使用了O_APPEND),否则该偏移量被设置为0。调用lseek函数显

式地为一个打开文件设置偏移量。该函数原型为:

#include <unistd.h>
off_t lseek(int fd,off_t offset,int whence);

该函数若成功则返回新的文件偏移量,若出错返回-1。参数fd为打开的文件描述符,参数offset与参数whence

的值有关:

  • 若whence是SEEK_SET,则将该文件的偏移量设置为距文件开始处offset个字节。
  • 若whence是SEEK_CUR,则将该文件的偏移量设置为其当前值加offset,offset可为正为负。
  • 若whence是SEEK_END,则将该文件的偏移量设置为文件长度加offset,offset可正可负。

若lseek成功执行,则返回新的文件偏移量。如果文件描述符指向的是一个管道、FIFO或网络套接字,则lseek

返回-1,并将errno设置为ESPIPE。

二、dup和dup2函数

dup和dup2系统调用都可以用来复制文件描述符,函数的原型为:

#include <unistd.h>
int dup(int fd);
int dup2(int fd,int fd2);

函数成功执行返回新的文件描述符,若出错返回-1。由dup返回的新文件描述符一定是当前可用文件描述符中的

最小数值。对于dup2,可以用fd2参数指定新的文件描述符的值。如果fd2已经打开,则先将其关闭。若fd等于fd2,

则dup2返回fd2,而不关闭它。否则,fd2的FD_CLOEXEC文件描述符标志就被清除,这样fd2在进程调用exec时是打

开状态。

dup(fd);等效于fcntl(fd,F_DUPFD,0);    dup2(fd,fd2);等效于close(fd2);fcntl(fd,F_DUPFD,fd2);

而dup2并不完全等同于close加上fcntl。它们之间的区别有:

(1)dup2是一个原子操作,而close和fcntl包括了两个函数调用。有可能在close和fcntl之间调用了信号捕获

函数,它可能修改文件描述符。如果不同的线程改变了文件描述符的话也会出现同样的问题。

(2)dup2和fcntl有一些不同的errno。

三、fcntl函数

fcntl系统调用可以用来对已经打开的文件描述符进行各种控制操作以改变已打开文件的各种属性,该函数的

原型为:

#include <unistd.h>
#include <fcntl.h>
int fcntl(int fd,int cmd,.../*int arg*/);

fcntl函数有以下5种功能:

(1)复制一个已有的文件描述符(cmd=F_DUPFD或F_DUPFD_CLOEXEC)。

(2)获取/设置文件描述符标志(cmd=F_GETFD或F_SETFD)。

(3)获取/设置文件状态标志(cmd=F_GETFL或F_SETFL)。

(4)获取/设置异步I/O所有权(cmd=F_GETOWN或F_SETOWN)。

(5)获取/设置记录锁(cmd=F_GETLK、F_SETLK或F_SETLKW)。

F_DUPFD:复制文件描述符fd。新文件描述符作为函数值返回。它是尚未打开的各描述符中大于或等于第3个

参数值(取为整型值)中各值的最小值。新文件描述符与fd共享同一文件表项。但是新的文件描述符有它自己的

一套文件描述符标志,其FD_CLOEXEC文件描述符标志被清除(这表示该文件描述符在exec时仍保持有效)。

F_DUPFD_CLOEXEC:复制文件描述符,设置与新的文件描述符关联的FD_CLOEXEC文件描述符标志的值,返回

新的文件描述符。

F_GETFD:对应于fd的文件描述符标志作为函数值返回当前只定义了一个文件描述符标志FD_CLOEXEC。

F_SETFD:对于fd设置文件描述符标志。新标志值按第3个参数(取为整型值)设置。

F_GETFL:对应于fd的文件状态标志作为函数值返回。

F_SETFL:将文件状态标志设置为第3个参数的值(取为整型值)。可以更改的几个标志为:O_APPEND、O_NO

NBLOCK、O_SYNC、O_DSYNC、O_RSYNC、O_FSYNC和O_ASYNC。

F_GETOWN:获取当前接收SIGIO和SIGURG信号的进程ID或进程组ID。

F_SETOWN:设置接收SIGIO和SIGURG信号的进程ID或进程组ID。正的arg指定一个进程ID,负的arg表示等于

arg绝对值的一个进程组ID。

fcntl的返回值与命令有关。如果出错,所有命令都返回-1,如果成功则返回某个其它值。F_DUPFD返回新的

文件描述符,F_GETFD和F_GETFL返回相应的标志,F_GETOWN返回一个正的进程ID或负的进程组ID。

四、ioctl函数

ioctl系统调用通常用来控制设备,不能用其它函数进行的控制操作都可以用ioctl来进行,该函数原型为:

#include <unistd.h>
#include <sys/ioctl.h>
int ioctl(int fd,int request,...);

ioctl用来控制特殊设备文件的属性,第一个参数fd必须是一个已经打开的文件描述符,第三个参数一般为

char *argp,它随第二个参数request的不同而不同。参数request决定了参数argp是向ioctl传递数据还是从io

ctl获取数据。

五、readv和writev函数

readv函数将数据从文件描述符读到分散的内存块中,即分散读;writev函数则将多块分散的内存数据一并

写入文件描述符中,即集中写。函数的原型为:

#include <sys/uio.h>
ssize_t readv(int fd,const struct iovec *iov,int count);
ssize_t writev(int fd,const struct iovec *iov,int count);

函数中fd参数是被操作的目标文件描述符。iov参数的类型是iovec结构数组,该结构体描述一块内存区。参

数count是iov数组的长度,即有多少块内存数据需要从fd读出或写到fd。readv和writev函数在成功时返回读出/

写入fd的字节数,失败则返回-1并设置errno。

六、sendfile函数

sendfile函数在两个文件描述符之间直接传递数据(完全在内核中操作),从而避免了内核缓冲区和用户缓

冲区之间的数据拷贝,效率很高,被称为零拷贝。该函数的原型为:

#include <sys/sendfile.h>
ssize_t sendfile(int out_fd,int in_fd,off_t *offset,size_t count);

函数中in_fd参数是待读出内容的文件描述符,out_fd参数是待写入内容的文件描述符。offset参数指定从读

入文件流的哪个位置开始读,如果为空,则使用读入文件流默认的起始位置。count参数指定在文件描述符in_fd

和out_fd之间传输的字节数。sendfile函数成功时返回传输的字节数,失败则返回-1并设置errno。in_fd必须是一

个支持类似mmap函数的文件描述符,即它必须指向真实的文件,不能是socket和管道;而out_fd则必须是一个soc

ket。因此,sendfile函数几乎是专门为在网络上传输文件而设计的。

七、mmap和munmap函数

mmap函数用于申请一段内存空间,可以将这段内存空间作为进程间通信的共享内存,也可以将文件直接映射

到其中。munmap函数则释放由mmap创建的这段内存空间。函数原型为:

#include <sys/mman.h>
void* mmap(void *start,size_t length,int prot,int flags,int fd,off_t offset);
int munmap(void *start,size_t length);

函数中start参数允许用户使用某个特定的地址作为这段内存的起始地址,如果它被设置成NULL,则系统自动

分配一个地址。length参数指定内存段的长度。prot参数用来设置内存段的访问权限,它可以取以下几个值的按位

或:(1)PROT_READ:内存段可读。(2)PROT_WRITE:内存段可写。(3)PROT_EXEC:内存段可执行。(4)PRO

T_NONE:内存段不能被访问。

flags参数控制内存段内容被修改后程序的行为,它可以被设置为某些值的按位或(其中MAP_SHARED和MAP_PRIVATE

是互斥的,不能同时指定)。flags参数的常用值有:MAP_SHARED、MAP_PRIVATE、MAP_ANONYMOUS、MAP_FIXED、MA

P_HUGETLB。fd参数是被映射文件对应的文件描述符,它一般通过open系统调用获得。offset参数设置从文件的何

处开始映射(对于不需要读入整个文件的情况)。

mmap函数成功时返回指向目标内存区域的指针,失败则返回MAP_FAILED((void*)-1)并设置errno。munmap函数

成功时返回0,失败则返回-1并设置errno。

八、splice函数

splice函数用于在两个文件描述符之间移动数据,也是零拷贝操作。该函数的原型为:

#include <fcntl.h>
ssize_t splice(int fd_in,loff_t *off_in,int fd_out,loff_t *off_out,size_t len,unsigned int flags);

函数中fd_in参数是待输入数据的文件描述符,如果fd_in是一个管道文件描述符,那么off_in参数必须被设置

为NULL,如果fd_in不是一个管道文件描述符,那么off_in表示从输入数据流的何处开始读取数据,此时若off_in

被设置为NULL,则表示从输入数据流的当前偏移位置读入;若off_in不为NULL,则它将指出具体的偏移位置。fd_o

ut/off_out参数的含义与fd_in/off_in相同,不过用于输出数据流。len参数指定移动数据的长度;flags参数则控

制数据如何移动,它可以被设置为某些值的按位或,常用值为:SPLICE_F_MOVE、SPLICE_F_NONBLOCK、SPLICE_F_

MORE、SPLICE_F_GIFT。使用splice函数时,fd_in和fd_out必须至少有一个是管道文件描述符。splice函数调用成

功时返回移动字节的数量,它可能返回0,表示没有数据需要移动,这发生在从管道中读取数据(fd_in是管道文件

描述符)而该管道没有被写入任何数据时。splice函数失败时返回-1并设置errno。

九、tee函数

tee函数在两个管道文件描述符之间复制数据,也是零拷贝操作。它不消耗数据,因此源文件描述符上的数据仍

然可以用于后续的读操作。该函数原型为:

#include <fcntl.h>
ssize_t tee(int fd_in,int fd_out,size_t len,unsigned int flags);

该函数的参数的含义与splice相同(但fd_in和fd_out必须都是管道文件描述符)。tee函数成功时返回在两个文

件描述符之间复制的数据数量(字节数)。返回0表示没有复制任何数据。tee失败时返回-1并设置errno。

原文地址:https://www.cnblogs.com/XNQC1314/p/9201658.html

时间: 2024-11-12 14:02:13

Linux中文件I/O函数的相关文章

Linux中文件描述符和打开文件之间的关系

Linux中文件描述符和打开文件之间的关系 文件描述符: 在形式上是一个非负整数.实际上,它是一个索引值,指向内核为每一个进程所维护的该进程打开文件的记录表. Linux中的文件类型 Linux系统中把一切都看做文件,包括普通文件-.目录文件d.字符设备文件c.块设备文件b.符号链接文件l.文件描述符是内核为了高效管理已被打开的文件所创建的索引(一个非负整数),用于指代已被打开的文件,Linux下所有的的I/O操作的系统调用都是通过文件描述符执行.例如0表示标准输入.1表示标准输出.3表示标准错

Linux中文件的基本属性

一.用户及用户组 所有者(属主):一般为文件的创建者,谁创建了该文件,就自然的成为该文件的所有者,每个文件的所有者(属主)有且仅有一个.用ll命令可以看到文件的所有者. 所属组(属组):当某个用户创建了一个文件后,这个文件的所在组就是该用户所在的组,一个用户可以属于多个组但仅有一个主组,用ll命令可以看到文件的所有组. 其他人:除开文件的所有者和所属组之外的用户,系统的其它用户都是文件的其他者.比如创建了两个用户Tom和Jerry,Tom相对Jerry创建的文件来说就是其他人. 二.文件权限 L

linux 中文件类型和颜色的区分

linux 中文件类型和颜色的区分 to be  continued linux 中文件类型和颜色的区分,布布扣,bubuko.com

MD5的好处及linux中文件MD5校验和的应用

MD5算法简介: MD5全称是报文摘要算法(Message-Digest Algorithm5),此算法对任意长度的信息逐位进行计算,产生一个二进制长度为128位(十六进制长度就是32位)的"指纹"(或称"报文摘要"),不同的文件产生相同的报文摘要的可能性是非常非常之小的. Message Digest Algorithm MD5为计算机安全领域广泛使用的一种散列函数,MD5算法常常被用来验证网络文件传输的完整性,防止文件被人篡改.它是用复杂的数学算法求得的一个12

linux中文件的三种时间

Linux 中文件的三种时间 文件的三种时间: 1.        mtime 文件的修改时间 文件的内容发生改变.包括文件中空格数目.字符的变动再复原等这些看上去并不影响有效数据内容的操作. 有意的改变时间戳.Eg:使用touch –m –t 2016666666666fileName这样的命令故意改变mtime. 2.        ctime 文件的改变时间 文件的"属性"改变.Eg:文件的权限.属主.属组等. mtime发生改变和人为的改变atime的情况,Eg:touch –

linux中文件的三种time(atime,mtime,ctime)

linux下文件有3个时间的,分别是atime,mtime,ctime.有些博友对这3个时间还是比较迷茫和困惑的,我整理了下,写下来希望对博友们有所帮助. 1 这三个time的含义 简名 全名 中文名 含义 atime access time 访问时间 文件中的数据库最后被访问的时间 mtime modify time 修改时间 文件内容被修改的最后时间 ctime change time 变化时间 文件的元数据发生变化.比如权限,所有者等 2 如何查看这3个time [[email prote

Linux中文件权限、用户和用户组管理

1.文件权限 2.文件和目录rwx权限说明 文件rwx权限: r  :  可读,具有读取文件内容的权限(),如果没有r,vi/vim编辑器提示无法编辑(可强制编辑),echo可以追加或重定向. w :  可写,具有修改文件内容的权限 x  :  可执行,具有执行文件的权限. 需满足:文件本身具有可执行权限:普通用户还需具有r权限:root用户只要x权限就可执行.linux中可执行文件:*.sh     *.py     *.perl等等. 目录rwx权限: r  :  可读,查看目录下面文件及子

linux中文件/目录普通权限

权限 文件属性的查看############# ls -l filename/ls -ld dictionary-|rw-r--r--.|1| root| root|   46 |Oct  1 05:03 |filename- ---------  -  ----  ----    --  ------------  -------- 1    2         3    4      5      6      7             81."-":文件类型 -    ##普通

Linux中文件函数(一)

一.stat.fstat.fstatat.lstat函数 函数的原型为: #include <sys/stat.h> int stat(const char *restrict pathname,struct stat *restrict buf); int fstat(int fd,struct stat *buf); int lstat(const char *restrict pathname,struct stat *restrict buf); int fstatat(int fd,