linux电脑 网页,关于linux文件I/O详解linux网页制作 -电脑资料

文章简介讲解一下关于linux文件I/O的用法与注意事项,有需要的朋友参考,

Linux系统中的大多数文件I/O只用到5个函数:open,read,write,lseek及close。本专题所涉及的函数都被称为不带缓冲的I/O,不带缓冲指的是read或read都是通过内核的一个系统调用实现的,它们是POSIX.1和Single UNIX Specification的组成部分。我们将进一步讨论多个进程间的文件共享及所涉及的内核数据结构。

文件描述符

文件描述符是一个非负整数,当使用open或create时,会返回一个文件描述符来标识该文件,可将其作为参数传递给read或write使用。文件描述符0(符号常量:STDIN_FILENO)与进程的标准输入相关联,文件描述符1(符号常量:STDOUT_FILENO)与进程的标准输出相关联,文件描述符2(符号常量:STDERR_FILENO)与进程的标准输出相关联,这些常量都定义在中。文件描述符的范围是0~OPEN_MAX,OPEN_MAX的值可以通过函数调用sysconf( _SC_OPEN_MAX );取得,下面是一个示例:

#include

#include

int

main( void )

{

long open_max = sysconf( _SC_OPEN_MAX );

printf( "%dn", open_max );

return 0;

}

输出:1024

open函数

#include

int open( const char* pathname, int oflag, .../* mode_t mode */ );

用以下一个或多个常量进行“或”运算构成oflag参数(这些常量在中定义):

O_RDONLY,O_WRONLY,O_RDWR 这三个常量必须且只能指定一个。

以下常量可选择一个或多个:

O_APPEND   在文件尾端追加

O_CREAT    若此文件不存在,则创建。使用此选项时,要用到mode参数以设定新文件的访问权限。

O_EXCL     测试一个文件是否存在。

O_TRUNC    如果文件成功打开,则将其长度截短为0。

O_NOCTTY   如果pathname参数指的是终端设备,则不将该设备作为此进程的控制终端。

O_NONBLOCK 如果pathname指的是一个FIFO,块特殊文件或字符特殊文件,则该选项为文件的本次打开操作和后续的I/O操作设置非阻塞模式。

注:*非阻塞模式:在I/O操作不能完成时,调用立即出错并返回,而不是永远等待。

O_DSYNC    使该文件所有的write操作等待,直到对该文件所有的I/O操作都完成之后,但是如果write操作不影响读取刚写入的数据时,则不用等待文件属性被更新。

O_RSYNC    使该文件所有的read操作等待,直到对该文件所有的write操作都完成之后。

O_SYNC     使该文件所有的write操作等待,直到对该文件所有的I/O操作都完成之后。

注:*Linux2.4.22将O_DSYNC和O_RSYNC处理成与O_SYNC相同,即文件的数据和属性总是同步更新。

close函数

#include

int close( int file_des );

关闭一个文件时,会释放该文件上的所有记录锁。进程终止时,内核会自动关闭它所打开的所有文件,但是显式调用close函数更安全。

lseek函数

#include

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

whence取值:

SEEK_SET   将文件的读写偏移量设置为距离文件首段offset个字节处。

SEEK_CUR   将文件的读写偏移量设置为距离当前值加offset个字节处,offset可为正负。

SEEK_END   将文件的读写偏移量设置为距离文件尾端offset个字节处,offset可为正负。

成功时返回新的文件偏移量,失败时返回-1。利用返回值可以测试文件描述符是否能够设置读写偏移量(管道,FIFO和网络套接字不能设置偏移量)。当读写偏移量大于文件长度时,写操作将会在文件中构成一个空洞,空洞被读为0,但是空洞并不占用磁盘空间,其处理方式与文件系统的实现有关。下面的程序将创建一个具有空洞的文件:

#include

#include

#include

#include

#include

char buf[] = "1234567890";

char buf2[] = "abcdefghij";

int

main( void )

{

remove( "file.hole" );

int file_des = open( "file.hole", O_RDWR|O_CREAT|O_EXCL, S_IRUSR|S_IWUSR|S_IXUSR );

if ( file_des == -1 )

{

write( STDOUT_FILENO, "OPEN FILE ERROR!n", 20 );

exit( 0 );

}

if ( lseek( file_des, 5, SEEK_SET ) == -1 )

{

write( STDOUT_FILENO, "FIRST SEEK ERROR!n", 20 );

exit( 0 );

}

size_t write_bytes = write( file_des, buf, strlen( buf ) );

if ( write_bytes < strlen( buf ) )

{

write( STDOUT_FILENO, "FIRST WRITE ERROR!n", 20 );

exit( 0 );

}

if ( lseek( file_des, 5, SEEK_END ) == -1 )

{

write( STDOUT_FILENO, "SECOND SEEK ERROR!n", 20 );

exit( 0 );

}

write_bytes = write( file_des, buf2, strlen( buf ) );

if ( write_bytes < strlen( buf2 ) )

{

write( STDOUT_FILENO, "SECOND WRITE ERROR!", 20 );

exit( 0 );

}

close( file_des );

return 0;

}

使用命令od查看文件file.hole的内容:

[root@localhost CC++]# od -c file.hole

0000000       1  2  3  4  5  6  7  8  9  0

0000020      a  b  c  d  e  f  g  h  i  j

可以看到,文件的开始处有一个空洞,中间有一个空洞,都被读为0,关于linux文件I/O详解linux网页制作》(https://www.unjs.com)。

read和write函数:

#include

ssize_t read( int file_des, void *buf, size_t nbytes );

返回值:成功返回读到的字节数,若已到文件结尾返回0,出错返回-1。

ssize_t write( int file_des, const void *size_t, size_t nbytes );

返回值:成功返回已写的字节数,出错返回-1。

pread和pwrite函数:

#include

ssize_t pread(int file_des, void *buf, size_t nbytes, off_t off_set);

ssize_t pwrite( int file_des, const void *buf, size_t nbytes, off_t off_set );

注:*pread和pwrite函数使lseek和read/write操作成为一个原子操作,pread/pwrite和lseek/read/write的重要区别在于:

调用pread/pwrite时,无法中断定位和读(写)操作;

pread/pwrite不能更新文件指针,可以使用ftell或fgetpos函数获取当前读写位置。

dup和dup2函数:

#include

int dup( int file_des );

int dup2( int file_des, int file_des2 );

dup和dup2都用于复制一个现有的文件描述符,成功返回新的文件描述符,出错返回-1,区别是:

dup一定返回当前可用的最小文件描述符;

dup2指定参数file_des2为新的文件描述符,当file_des2打开时,先将其关闭,若file_des和file_des2相等,返回file_des2而不关闭它。

注:*fcntl函数也可以复制文件描述符,稍后将会介绍。

sync,fsync和fdatasync函数:

#include

int sync( void );

int fsync( int file_des );

int fdatasync( int file_des );

以上函数都用于保证物理文件和高速缓存数据的一致性,区别是:sync只是将所有修改过的块缓冲区排入写队列,并不等待写磁盘操作的完成就返回;fsync只是针对由文件描述符指向的单一文件,并且等待写磁盘操作完成再返回,但它只影响文件的数据部分;fdatasync和fsync类似,但除了数据之外,fdatasync还会同步更新文件的属性。

fcntl函数:

#include

int fcntl( int files_des, int cmd, .../* int arg */ );

fcntl函数可以改变已经打开的文件的性质。

cmd参数取值(一共有10中,这里先介绍前7种):

F_DUPFD   复制文件描述符files_des,新文件描述符作为函数返回值返回。新描述符有自己的文件描述符标志,其FD_CLOEXEC文件描述符标志被清除。

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

F_SETFD   对于files_des设置文件描述符标志,新标志值按第三个参数设置。

F_GETFL   对应于files_des的文件状态标志作为函数值返回。文件状态标志在open函数已经说明。

F_SETFL   将文件状态标志设置为第三个参数的值。可以更改的标志是:O_APPEND,O_NONBLOCK,O_SYNC,O_DSYNC,O_RSYNC,O_FSYNC,0_ASYNC。

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

F_SETOWN  设置接收SIGIO和SIGURG信号的进程ID或进程租ID。正的arg参数表示一个进程ID,负的arg参数表示等于arg的绝对值的进程租ID。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值