文件IO操作open()-close()-read()和write()函数详解_第1页
文件IO操作open()-close()-read()和write()函数详解_第2页
文件IO操作open()-close()-read()和write()函数详解_第3页
文件IO操作open()-close()-read()和write()函数详解_第4页
文件IO操作open()-close()-read()和write()函数详解_第5页
已阅读5页,还剩3页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

文件I/O操作open(),close(),read()和write()函数详解1.open〔〕函数功能描述:用于翻开或创立文件,在翻开或创立文件时可以指定文件的属性及用户的权限等各种参数。所需头文件:#include<sys/types.h>,#include<sys/stat.h>,#include<fcntl.h>函数原型:intopen(constchar*pathname,intflags,intperms)参数:pathname:被翻开的文件名〔可包括路径名如"dev/ttyS0"〕flags:文件翻开方式,O_RDONLY:以只读方式翻开文件O_WRONLY:以只写方式翻开文件O_RDWR:以读写方式翻开文件O_CREAT:如果改文件不存在,就创立一个新的文件,并用第三个参数为其设置权限O_EXCL:如果使用O_CREAT时文件存在,那么返回错误消息。这一参数可测试文件是否存在。此时open是原子操作,防止多个进程同时创立同一个文件O_NOCTTY:使用本参数时,假设文件为终端,那么该终端不会成为调用open()的那个进程的控制终端

O_TRUNC:假设文件已经存在,那么会删除文件中的全部原有数据,并且设置文件大小为0

O_APPEND:以添加方式翻开文件,在翻开文件的同时,文件指针指向文件的末尾,即将写入的数据添加到文件的末尾O_NONBLOCK:如果pathname指的是一个FIFO、一个块特殊文件或一个字符特殊文件,那么此选择项为此文件的本次翻开操作和后续的I/O操作设置非阻塞方式。O_SYNC:使每次write都等到物理I/O操作完成。

O_RSYNC:read等待所有写入同一区域的写操作完成后再进行

在open()函数中,falgs参数可以通过“|”组合构成,但前3个标准常量〔O_RDONLY,O_WRONLY,和O_RDWR〕不能互相组合。perms:被翻开文件的存取权限,可以用两种方法表示,可以用一组宏定义:S_I(R/W/X)(USR/GRP/OTH),其中R/W/X表示读写执行权限,USR/GRP/OTH分别表示文件的所有者/文件所属组/其他用户,如S_IRUUR|S_IWUUR|S_IXUUR,〔-rex------〕,也可用八进制800表示同样的权限返回值:成功:返回文件描述符失败:返回-1

2.close〔〕函数功能描述:用于关闭一个被翻开的的文件所需头文件:

#include<unistd.h>函数原型:intclose(intfd)参数:fd文件描述符函数返回值:0成功,-1出错3.read〔〕函数功能描述:从文件读取数据。

所需头文件:

#include<unistd.h>函数原型:ssize_tread(intfd,void*buf,size_tcount);参数:

fd:

将要读取数据的文件描述词。

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

count:表示调用一次read操作,应该读多少数量的字符。返回值:返回所读取的字节数;0〔读到EOF〕;-1〔出错〕。以下几种情况会导致读取到的字节数小于

count:

A.读取普通文件时,读到文件末尾还不够

count字节。例如:如果文件只有30字节,而我们想读取100

字节,那么实际读到的只有30字节,read函数返回30。此时再使用read函数作用于这个文件会导致read返回0。

B.从终端设备〔terminaldevice〕读取时,一般情况下每次只能读取一行。

C.从网络读取时,网络缓存可能导致读取的字节数小于count字节。

D.读取pipe或者FIFO时,pipe或FIFO里的字节数可能小于

count。

E.从面向记录〔record-oriented〕的设备读取时,某些面向记录的设备〔如磁带〕每次最多只能返回一个记录。

F.在读取了局部数据时被信号中断。

读操作始于cfo。在成功返回之前,cfo增加,增量为实际读取到的字节数。4.write〔〕函数功能描述:向文件写入数据。

所需头文件:

#include<unistd.h>函数原型:ssize_twrite(intfd,void*buf,size_tcount);返回值:写入文件的字节数〔成功〕;-1〔出错〕功能:write函数向filedes中写入

count字节数据,数据来源为buf。返回值一般总是等于count,否那么就是出错了。常见的出错原因是磁盘空间满了或者超过了文件大小限制。对于普通文件,写操作始于cfo。如果翻开文件时使用了O_APPEND,那么每次写操作都将数据写入文件末尾。成功写入后,cfo增加,增量为实际写入的字节数。

1.lseek〔〕函数

功能描述:用于在指定的文件描述符中将将文件指针定位到相应位置。

所需头文件:

#include<unistd.h>,#include<sys/types.h>函数原型:off_tlseek(intfd,off_toffset,intwhence);参数:fd;文件描述符offset:偏移量,每一个读写操作所需要移动的距离,单位是字节,可正可负〔向前移,向后移〕whence:SEEK_SET:当前位置为文件的开头,新位置为偏移量的大小SEEK_CUR:当前位置为指针的位置,新位置为当前位置加上偏移量SEEK_END:当前位置为文件的结尾,新位置为文件大小加上偏移量的大小返回值:成功:返回当前位移失败:返回-1函数实例:功能是从一个文件〔源文件〕中读取最后的10K数据复制到另一个文件〔目标文件〕。实例中原文件以只读方式翻开,目标文件以只写方式翻开。假设目标文件不存在,可以创立并设置权限为644。#include<stdio.h>#include<stdlib.h>

#include<unistd.h>#include<sys/types.h>

#include<sys/stat.h>

#include<fcntl.h>#defineBUFFER_SIZE1024

//每次读写缓存大小,影响运行效率

#defineSRC_FILE_NAME"src_file"

//源文件名

#defineDEST_FILE_NAME"dest_file"

//目标文件名

#defineOFFSET10240

//复制的数据大小intmain()

{

intsrc_file,dest_file;

unsignedcharbuff[BUFFER_SIZE];

intreal_read_len;

src_file=open(SRC_FILE_NAME,O_RDONLY);

//以只读方式翻开源文件

dest_file=open(DEST_FILE_NAME,O_RDWR|O_CREAT,S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);

if(src_file<0||dest_file<0)

{

printf("openfileerror!!!\n");

exit(1);

}

lseek(src_file,-OFFSET,SEEK_END);

//将源文件的读写指针移到最后10K的起始位置

while((real_read_len=read(src_file,buff,sizeof(buff)))>0)

{

write(dest_file,buff,real_read_len);

}

close(src_file);

close(dest_file);

return0;

}

现象分析:1.运行前如果目录下没有src_file,会出现以下现象

2.有了源文件,但源文件小于10K,会把源文件的所有数据复制到目标文件3.如果源文件大于10K,那么会把源文件最后的10K复制到目标文件中

利用UTL_FILE包实现文件I/O操作文件I/O对于数据库的开发来说显得很重要,比方如果数据库中的一局部数据来自于磁盘文件,那么就需要使用I/O接口把数据导入到数据库中来。在PL/SQL中没有直接的I/O接口,一般在调试程序时可以使用Oracle自带的DBMS_OUTPUT包的put_line函数〔即向屏幕进行I/O操作〕即可,但是对于磁盘文件的I/O操作它就无能为力了。其实Oracle同样也提供了可以进行文件I/O的实用包-----UTL_FILE包,利用这个实用包提供的函数来实现对磁盘的I/O操作。1.准备工作由于Oracle数据库对包创立的目录有一个平安管理的问题,所以并不是所有的文件目录能够被UTL_FILE包所访问,要更新这种目录设置,就得到init.ora里将UTL_FILE_DIR域设置为*,这样UTL_FILE包就可以对所有的目录文件进行访问了。2.文件I/O的实施UTL_FILE包提供了很多实用的函数来进行I/O操作,主要有以下几个函数:fopen翻开指定的目录路径的文件。get_line获取指定文件的一行的文本。put_line向指定的文件写入一行文本。fclose关闭指定的文件。下面利用这些函数,实现从文件取数据,然后将数据写入到相应的数据库中。createorreplaceprocedureloadfiledata(p_pathvarchar2,p_filenamevarchar2)as

v_filehandleutl_file.file_type;--定义一个文件句柄

v_textvarchar2(100);--存放文本

v_nametest_%type;

v_addr_jdtest_loadfile.addr_jd%type;

v_regiontest_loadfile.region%type;

v_firstlocationnumber;

v_secondlocationnumber;

v_totalinsertednumber;

begin

if(p_pathisnullorp_filenameisnull)then

gototo_end;

endif;

v_totalinserted:=0;

/*openspecifiedfile*/

v_filehandle:=utl_file.fopen(p_path,p_filename,'r');

loop

begin

utl_file.get_line(v_filehandle,v_text);

exception

whenno_data_foundthen

exit;

end;

v_firstlocation:=instr(v_text,',',1,1);

v_secondlocation:=instr(v_text,',',1,2);

v_name:=substr(v_text,1,v_firstlocation-1);

v_addr_jd:=substr(v_text,v_firstlocation+1,v_secondlocation-v_firstlocation-1);

v_region:=substr(v_text,v_secondlocation+1);

/*插入数据库操作*/

insertintotest_loadfile

values(v_name,v_addr_jd,v_region);

commit;

endloop;

<<to_end>>

null;

endloadfiledata;

/

3.测试环境首先要创立一个目标表TEST_LOADFILE,它用来存储文件中的数据:CREATETABLETEST_LOADFILE(

NAMEVARCHAR2(100)NOTNULL,

ADDR_JDVARCHAR2(20),

REGIONVARCHAR2(6));然后就可以在sqlplus里输入如下的代码并执行即可。declare

v_pathvarchar2(200);

v_filenamevarchar2(200);

begin

v_path:='F:';

v_filename:='地址信息.txt';

loadfiledata(v_path,v_filename);

end;

/

需要注意的是,这里我的调试路径为“f:”地址,如果读者自己建立实验环境,应该设置为的“地址信息”文件的路径整个调试环境是:效劳器端:UNIX操作系统+Oracle9i数据库效劳器,客户端:sqlplus,操作系统为WIN2000。4.小结Oracle本身提供了大量使用的包,如UTL_HTTP包,DBMS_OUTPUT包等,这些包分别封装了不同的功能,它们使得进行大量的应用程序开发的可能,从而拓展了Oracle的功能。linux文件I/O操作之前有介绍过关于文件的指针和描述符,这次通过一个练习,熟悉了一下文件的open,close,read,write,sleek,dup等操作,一些主要的考前须知详见代码注释吧。

ps:局部代码写的有些龌龊,也和硬要把几个函数都试到有关,应该可以用更好的方法。fighting~~~

【功能】命令行输入三个参数,将data.dat文件中的内容拷贝到data2.dat中,并搜索data2.dat中hello出现的次数,消息打印重定向到dupfile.dat中。

【代码实现】#include<sys/stat.h>

#include<sys/types.h>

#include<fcntl.h>

#include<stdio.h>

#include<string.h>

#include<unistd.h>intmain(intargc,char*argv[])

{

intfd1;

intfd2;

intfd3;

charbuffer[100];

intnum;

intflag=0;

intlen;

intoffset=0;

if(4!=argc)

{

printf("Usage:%ssourcefile,destfile,keyword.\n",argv[0]);

return1;

}

//testfunction:open(),close(),read(),write()

//翻开文件,如果文件不存在,允许按照参数给定权限创立,这里文件data.dat为已经存在且写入一定内容的。

if((fd1=open(argv[1],O_CREAT|O_RDWR,0777))==-1)

{

perror("Can'topenthesourcefile.\n");

return1;

}

if((fd2=open(argv[2],O_CREAT|O_RDWR,0777))==-1)

{

perror("Can'topenthedestfile.\n");

return1;

}

while((num=read(fd1,buffer,5))>0)

{

buffer[num]='\0';

//防止读出乱码影响结果

if(write(fd2,buffer,num)==-1)

{

perror("Writetofiledata2.datfailed.\n");

return1;

}

}

close(fd1);

close(fd2);

//testfunction:lseek()

dup()

len=strlen(argv[3]);

if((fd2=open(argv[2],O_RDONLY))==-1)

{

perror("Can'topenthedestfile.\n");

return1;

}

while(1)

{//SEEK_SET参数表示每次都是直接用offset做偏移值,即在文件头的位置+offset;此外SEEK_CUR表示在当前位置根底上加offset偏移,SEEK_END表示偏移量为文件大小加offset值。

if(lseek(fd2,offset,SEEK_SET)==-1)

{

perror("Can'tmovethefilepointer.\n");

return1;

}

if((num=read(fd2,buffer,len))<len)

{//可读到的字符数小于要搜索的字符串长度,可以跳出

break;

}

else

{

buffer[len]='\0';

if(strcmp(buffer,argv[3])==0)

{

//找到匹配,计数+1

flag++;

}//无论是否匹配,offset都应该增加1,否那么文件指针一直不变,进入死循环

offset++;

}

}//关闭标准输出,并将翻开的文件描述符重定向到标准输出

close(STDOUT_FILENO);

if((fd3=open("dupfile.dat",O_CREAT|O_RDWR,0777))==-1)

{

perr

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论