open函数 write函数 以及 read函数 文件描述符

时间:2023-02-12 22:00:11

  open函数:头文件

#include<sys/types.h>  /*提供类型pid_t,size_t的定义*/

#include<sys/stat.h>

#include<fcntl.h>

函数原型

int open(const char *path, int oflags,mode_t mode);

函数说明

open建立了一条到文件或设备的访问路径。

open函数一般用于打开或者创建文件,在打开或创建文件时可以制定文件的属性及用户的权限等各种参数。

    

第一个参数path表示:路径名或者文件名。路径名为绝对路径名(如C:/cpp/a.cpp),否则文件则是在当前工作目录下的。

第二个参数oflags表示:打开文件所采取的动作。

    可能值:必须指定下面某一种:

    O_RDONLY(只读),

    O_WRONLY(只写),

    O_RDWR(可读可写)

打开/创建文件时,至少得使用上述三个常量中的一个,以下常量是选用的:

 O_APPEND      每次写操作都写入文件的末尾

O_CREAT        如果指定文件不存在,则创建这个文件

O_EXCL         如果要创建的文件已存在,则返回 -1,并且修改errno的值

O_TRUNC        如果文件存在,并且以只写/读写方式打开,则清空文件全部内容

O_NOCTTY       如果路径名指向终端设备,不要把这个设备用作控制终端。

O_NONBLOCK     如果路径名指向 FIFO/块文件/字符文件,则把文件的打开和后继 I/O

                       设置为非阻塞模式(nonblocking mode)

第三个参数mode表示:设置文件访问权限的初始值。

(与用户掩码umask变量有关,实际的访问权限有mode &~umask确定)

S_IRUSR,S_IWUSER,S_IXUSR,S_IRGRP,S_IWGRP,S_IXGRP,S_IROTH,S_IWOTH,S_IXOTH.其中R:读,W:写,X:执行,USR:文件所属的用户,GRP:文件所属的组,OTH:其他用户。

 

注:第三个参数是在第二个参数中有O_CREAT时才用作用。若没有,则第三个参数可以忽略。

返回值:如果操作成功,它将返回一个文件描述符,如果失败,返回-1

文件描述符:

文件描述符在形式上是一个非负整数。实际上,它是一个索引值,指向内核为每一个进程所维护的该进程打开文件的记录表。当程序打开一个现有文件或者创建一个新文件时,内核向进程返回一个文件描述符。在程序设计中,一些涉及底层的程序编写往往会围绕着文件描述符展开。但是文件描述符这一概念往往只适用于UNIXLinux这样的操作系统。习惯上,标准输入(standard input)的文件描述符是 0,标准输出(standard output)是 1,标准错误(standard error)是 2。尽管这种习惯并非Unix内核的特性,但是因为一些 shell 和很多应用程序都使用这种习惯,因此,如果内核不遵循这种习惯的话,很多应用程序将不能使用。POSIX 定义了 STDIN_FILENO、STDOUT_FILENO 和 STDERR_FILENO 来代替 0、1、2。这三个符号常量的定义位于头文件 unistd.h。文件描述符的有效范围是 0 到 OPEN_MAX。一般来说,每个进程最多可以打开 64 个文件(0 — 63)。对于 FreeBSD 5.2.1、Mac OS X 10.3 和 Solaris 9 来说,每个进程最多可以打开文件的多少取决于系统内存的大小,int 的大小,以及系统管理员设定的限制。Linux 2.4.22 强制规定最多不能超过 1,048,576 。文件描述符是由无符号整数表示的句柄,进程使用它来标识打开的文件。文件描述符与包括相关信息(如文件的打开模式、文件的位置类型、文件的初始类型等)的文件对象相关联,这些信息被称作文件的上下文。如何创建文件描述符进程获取文件描述符最常见的方法是通过本机子例程open或create获取或者通过从父进程继承。后一种方法允许子进程同样能够访问由父进程使用的文件。文件描述符对于每个进程一般是唯一的。当用fork子例程创建某个子进程时,该子进程会获得其父进程所有文件描述符的副本,这些文件描述符在执行fork时打开。在由fcntl、dup和dup2子例程复制或拷贝某个进程时,会发生同样的复制过程。对于每个进程,操作系统内核在u_block结构中维护文件描述符表,所有的文件描述符都在该表中建立索引。

收藏:读函数read  
ssize_t read(int fd,void *buf,size_t nbyte) 
read函数是负责从fd中读取内容.成功时,read返回实际所读的字节数,如果返回的值是0,表示已经读到文件的结束了.小于0表示出现了错误.如果错误为EINTR说明读是由中断引起的, 如果是ECONNREST表示网络连接出了问题.写函数write  
ssize_t write(int fd,const void *buf,size_t nbytes) 
write函数将buf中的nbytes字节内容写入文件描述符fd.成功时返回写的字节数.失败时返回-1. 并设置errno变量. 在网络程序中,当我们向套接字文件描述符写时有俩种可能.  
1)write的返回值大于0,表示写了部分或者是全部的数据.  
2)返回的值小于0,此时出现了错误.我们要根据错误类型来处理.  如果错误为EINTR表示在写的时候出现了中断错误.  
如果为EPIPE表示网络连接出现了问题(对方已经关闭了连接).









 Linux-read函数 收藏
 

read函数(读取文件)

read函数可以读取文件。读取文件指从某一个已打开地文件中,读取一定数量地字符,然后将这些读取的字符放入某一个预存的缓冲区内,供以后使用。

使用格式如下:

number = read( ...

read函数(读取文件)

read函数可以读取文件。读取文件指从某一个已打开地文件中,读取一定数量地字符,然后将这些读取的字符放入某一个预存的缓冲区内,供以后使用。

使用格式如下:

number = read(handle, buffer ,n) ;

上述read调用函数中,各个参数的定义如下:

handle: 这是一个已经打开的文件句柄,表示从这个文件句柄所代表的文件读取数据。

buffer: 指缓冲区,即读取的数据会被放到这个缓冲区中去。

n: 表示调用一次read操作,应该读多少数量的字符。

number:表示系统实际所读取的字符数量。

假设某个文件的长度是600字符,而n的值是512,则在第1次调用读这个文件时,系统可以正常地读取512个字符地内容,并将这些字符数量传给number变量,因此number的值将变为88。要第2次读取这个文件时,因为文件已经没有内容可供读取了,此时系统会返回0给number。另外,如果读取文件失败,系统将返回-1给number。

比如一个有100个字节的文件,第一次读取10个字节,这时读取指针在第10个字节处。再次进行10个字节的读操作时,会接着第一次读的位置接着往后读。如果还想从开始读,可使用lseek函数定位。

Code:

#include "lyl.h"

#define BUF 512

main()

{

static char filename[]="t1.txt" ;

char buffer[BUF] ;

int handle ;

int i ;

int total = 0 ;

handle = open(filename,O_RDONLY) ;

if ( handle == -1 )

{

printf("[%s] create fail !!!!

",filename) ;

exit(1) ;

}

else

{

while( (i = read(handle,buffer,BUF) ) > 0 )

total =i ;

}

printf("The total character in 《%s》 is %d

",filename,total ) ;

exit(0) ;

}

程序执行结果:

The total character in 《t1.txt》 is 11

$cat t1.txt

1234567890

 

 

【 read系统调用】  
   
功能描述:
从文件读取数据。
 
用法: 
#include <unistd.h>

ssize_t read(int fd, void *buf, size_t count);


参数:  
fd: 将要读取数据的文件描述词。
buf:  所读取到的数据的内存缓冲。
count: 需要读取的数据量。
   
返回说明:  
成功执行时,返回所读取的数据量。失败返回-1,errno被设为以下的某个值  
EAGAIN:打开文件时设定了O_NONBLOCK标志,并且当前没有数据可读取
EBADF:文件描述词无效,或者文件不可读
EFAULT:参数buf指向的空间不可访问
EINTR:数据读取前,操作被信号中断
EINVAL:一个或者多个参数无效
EIO:读写出错
EISDIR:参数fd索引的时目录


 备注:

从串口读数据,只读一次,数据没有读全。加入while后,则数据读全了。

total_read_bytes=0;

while(read_bytes=read(fd_485,buffer1,256)>0)

{

memcpy(buffer2+total_read_bytes,buffer1,read_bytes);

total_read_bytes+=read_bytes;

}

for(i=0;i<total_read_bytes;i++)

printf("0x%02lx\n",buffer2[i]);



write函数是C语言函数。

write函数所在的头文件为 <unistd.h>write有两种用法。一种是:ssize_twrite(int handle, void *buf, int nbyte);handle 是文件描述符buf是指定的缓冲区,即指针,指向一段内存单元;nbyte是要写入文件指定的字节数;返回值:写入文档的字节数(成功);-1(出错)write函数把buf中nbyte写入文件描述符handle所指的文档,成功时返回写的字节数,错误时返回-1.另一种是:write(const char* str,int n)str是字符指针或字符数组,用来存放一个字符串。n是int型数,它用来表示输出显示字符串中字符的个数。write("string",strlen("string");表示输出字符串常量