I/O -x open()-read()-write()-close()-lseek()

  大多数unix文件I/O只需要用到5个函数:open,read,write,lseek,close。这些函数都为不带缓存的I/O,不带缓存指的是每个read和write都调用内核中的一个系统调用。这些函数使用时要用到三个头文件:sys/types.h,sys/stat.h,fcntl.h

open函数:int open(const char path *name, int oflag,...);
  返回:若成功为只写打开的文件描述符,若错误为-1。
调用open函数可以打开或创建一个文件,仅当创建新文件时才使用第三个参数,由open函数返回的文件描述符一定是最小的未用的描述符数字。
  第一个参数为路径名
  第二个参数为文件状态标志:
O_RDONLY或0:可读
O_WRONLY或1:可写
O_RDWR或2:可执行
O_APPEND:每次写时都加到文件的尾部
O_CREAT:若此文件不存在则创建它,使用此选项时,需同时说明第三个参数mode,用其说明该新文件的存取许可权位
O_EXCL:如果同时指定了O_CREAT,而文件已经存在,则出错,这可测试一个文件是否存在,如果不存在则创建此文件成为一个原子操作
O_TRUNC:如果此文件存在,而且为只读或只写成功打开,则将其长度截短为0
O_NOCTTY:如果pathname指的是终端设备,则不将此设备分配作为此进程的控制终端
O_NONBLOCK:如果pathname指的是一个FIFO,一个块特殊文件或一个字符特殊文件,则此选择项为此文件的本次打开操作和后续的I/O操作设置非阻塞方式
O_SYNC:使每次write都等到物理I/O操作完成
  第三个参数一般为文件权限:
S_IRWXU,0700:代表该文件所有者具有可读,可写,可指向的权限
S_IRUSR或S_IREAD,0400:代表该文件所有者具有可读取的权限
S_IWUSR或S_IWRITE,0200:代表该文件所有者具有可写入的权限
S_IXUSR或S_IEXEC,0100:代表该文件所有者具有可指向的权限
S_IRWXG,0070:代表该文件用户组具有可读,可写,可执行的权限
S_IRGRP,0040:代表该文件用户组具有可读的权限
S_IWGRP,0020:代表该文件用户组具有可写的权限
S_IXGRP,0010:代表该文件用户组具有可执行的权限
S_IRWXO,0007:代表其他用户具有可读,可写,可执行的权限
S_IROTH,0004:代表其他用户具有可读的权限
S_IWOTH,0002:代表其他用户具有可写的权限
S_IXOTH,0001:代表其他用户具有可执行的权限

creat函数:int creat(const char *pathname, mode_t mode);
  返回:若成功为只写打开的文件描述符,若出错为-1
  该函数等效于:open(pathname,O_WRONLY|O_CREAT|O_TRUNC,mode);
  用于创建一个新文件

 

read函数 :ssize_t read (int fd, void *buf, size_t count);
返回值
成功返回读取的字节数,出错返回-1并设置errno,如果在调read之前已到达文件末尾,则这次read返回0。
参数
参数count是请求读取的字节数,读上来的数据保存在缓冲区buf中,同时文件的当前读写位置向后移。


注意这个读写位置和使用C标准I/O库时的读写位置有可能不同,这个读写位置是记在内核中的,而使用C标准I/O库时的读写位置是用户空间I/O缓冲区中的位置。
比如用fgetc读一个字节,fgetc有可能从内核中预读1024个字节到I/O缓冲区中,再返回第一个字节,这时该文件在内核中记录的读写位置是1024,而在FILE结构体中记录的读写位置是1。注意返回值类型是ssize_t,表示有符号的size_t,这样既可以返回正的字节数、0(表示到达文件末尾)也可以返回负值-1(表示出错)。
read函数返回时,返回值说明了buf中前多少个字节是刚读上来的。有些情况下,实际读到的字节数(返回值)会小于请求读的字节数count,例如:读常规文件时,在读到count个字节之前已到达文件末尾。例如,距文件末尾还有30个字节而请求读100个字节,则read返回30,下次read将返回0。

 1 #include <stdio.h>
 2 #include <io.h>
 3 #include <alloc.h>
 4 #include <fcntl.h>
 5 #include <process.h>
 6 #include <sys\stat.h>
 7 int main(void)
 8 {
 9 void* buf ;
10 int handle;
11 int bytes ;
12 buf=malloc(10);
13 /*
14 LooksforafileinthecurrentdirectorynamedTEST.$$$andattempts
15 toread10bytesfromit.Tousethisexampleyoushouldcreatethe
16 fileTEST.$$$
17 */
18 handle=open("TEST.$$$",O_RDONLY|O_BINARY,S_IWRITE|S_IREAD);
19 if(handle==-1)
20 {
21 printf("ErrorOpeningFile\n");
22 exit(1);
23 }
24 bytes=read(handle,buf,10);
25 if(bytes==-1)
26 {
27 printf("ReadFailed.\n");
28 exit(1);
29 }
30 else 
31 {
32 printf("Read:%dbytesread.\n",bytes);
33 }
34 return0 ;
35 }

 

write(将数据写入已打开的文件内)
表头文件
#include<unistd.h>
定义函数
ssize_t write (int fd,const void * buf,size_t count);
函数说明
write()会把指针buf所指的内存写入count个字节到参数fd所指的文件内。当然,文件读写位置也会随之移动。
返回值
如果顺利write()会返回实际写入的字节数。当有错误发生时则返回-1,错误代码存入errno中。
错误代码
EINTR 此调用被信号所中断。
EAGAIN 当使用不可阻断I/O 时(O_NONBLOCK),若无数据可读取则返回此值。
EBADF 参数fd非有效的文件描述词,或该文件已关闭。

函数名: write
功 能: 写到一文件中
用 法: int write(int handle, void *buf, int nbyte);
程序例:

 1 #include<stdlib.h>
 2 #include<unistd.h>
 3 #include<stdio.h>
 4 #include<string.h>
 5 #include<fcntl.h>
 6 #include<errno.h>
 7 intmain(void)
 8 {
 9 inthandle;
10 charstring[40];
11 intlength,res;
12 /*
13 Createafilenamed"TEST.$$$"inthecurrentdirectoryandwrite
14 astringtoit.If"TEST.$$$"alreadyexists,itwillbeoverwritten.
15 */
16 if((handle=open("TEST.$$$",O_WRONLY|O_CREAT|O_TRUNC,
17 S_IREAD|S_IWRITE))==-1)
18 {
19 printf("Erroropeningfile.\n");
20 exit(1);
21 }
22 
23 strcpy(string,"Hello,world!\n");
24 length=strlen(string);
25 
26 if((res=write(handle,string,length))!=length)
27 {
28 printf("Errorwritingtothefile.\n");
29 exit(1);
30 }
31 
32 printf("Wrote%dbytestothefile.\n",res);
33 close(handle);
34 return0;
35 }
1 structxfcb{
2 charxfcb_flag;/*Contains0xfftoindicatexfcb*/
3 charxfcb_resv[5];/*ReservedforDOS*/
4 charxfcb_attr;/*Searchattribute*/
5 structfcbxfcb_fcb;/*Thestandardfcb*/
6 };

 

名称 : write
使用权限 : 所有使用者
使用方式 :
write user [ttyname]
说明 : 传讯息给其他使用者
user : 预备传讯息的使用者帐号
ttyname : 如果使用者同时有两个以上的 tty 连线,可以自行选择合适的 tty 传讯息
例子.1 :
传讯息给 Rollaend,此时 Rollaend 只有一个连线 :
write Rollaend
接下来就是将讯息打上去,结束请按 ctrl+c
例子.2 :传讯息给 Rollaend,Rollaend 的连线有 pts/2,pts/3 :
write Rollaend pts/2
接下来就是将讯息打上去,结束请按 ctrl+c
注意 : 若对方设定 mesg n,则此时讯息将无法传给对方

 

close函数:int close(int filedes);
  返回:若成功为0,若出错为-1
  关闭一个文件时也释放该进程加在该文件上的所有记录锁,当一个进程终止时,它所有的打开文件都由内核自动关闭。

 

lseek函数:off_t lseek(int filedes, off_t offset, int whence);
  返回:若成功为新的文件位移,若出错为-1
  每个打开文件都有一个与其相关联的”当前文件位移量”,它是一个非负整数,用以度量从文件开始处计算的字节数。按系统默认,当打开一个文件时,除非指定O_APPEND选项时,否则该位移量被设置为0。通常读,写操作都从当前文件位移量处开始,并使位移量增加所读或写的字节数。可以调用lseek显式地定位一个打开的文件。
  对参数offset的解释与参数whence的值有关。
    若whence是SEEK_SET,则将该文件的位移量设置为距文件开始处offset个字节
    若whence是SEEK_CUR,则将该文件的位移量设置为其当前值加offset,offset可为正或负
    若whence是SEEK_END,则将该文件的位移量设置为文件长度加offset,offset可为正或负
早期用0,1,2代铁SEEK_SET,SEEK_CUR,SEEK_END。
某些设备也可能允许负的位移量,但对于普通文件,则其位移量必须是非负值
范例:

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 #include <sys/types.h>
 4 #include <sys/stat.h>
 5 #include <fcntl.h>
 6 int main(void)
 7 {
 8 int fd, size;
 9 char buf1[]="Hello, world";
10 char buf2[50];
11 if((fd=open("/home/sam/helloworld",O_CREAT|O_TRUNC|O_RDWR,0666))==-1)
12 {
13 printf("Open or create file named \"helloworld\" failed.\n");
14 exit(1);
15 }
16 write(fd,buf1,sizeof(buf1));
17 close(fd);
18 if((fd=open("/home/sam/helloworld",O_RDONLY))==-1)
19 {
20 printf("Open file named \"helloworld\" failed.\n");
21 exit(1);
22 }
23 size=read(fd,buf2,sizeof(buf2));
24 close(fd);
25 printf("%s\n",buf2);
26 if((fd=open("/home/sam/helloworld",O_RDONLY))==-1)
27 {
28 printf("Open file named \"helloworld\" failed.\n");
29 exit(1);
30 }
31 lseek(fd,6,SEEK_SET);
32 size=read(fd,buf2,sizeof(buf2));
33 printf("%s\n",buf2);
34 close(fd);
35 return 0;
36 }

 

相关函数
fcntl,lseek,sync,fsync,fwrite

posted @ 2015-05-16 13:24  pencil_zh  阅读(829)  评论(0编辑  收藏  举报