文件IO操作open()-close()-read()和write()函數(shù)詳解_第1頁
文件IO操作open()-close()-read()和write()函數(shù)詳解_第2頁
文件IO操作open()-close()-read()和write()函數(shù)詳解_第3頁
文件IO操作open()-close()-read()和write()函數(shù)詳解_第4頁
文件IO操作open()-close()-read()和write()函數(shù)詳解_第5頁
已閱讀5頁,還剩3頁未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

文件I/O操作open(),close(),read()和write()函數(shù)詳解1.open〔〕函數(shù)功能描述:用于翻開或創(chuàng)立文件,在翻開或創(chuàng)立文件時(shí)可以指定文件的屬性及用戶的權(quán)限等各種參數(shù)。所需頭文件:#include<sys/types.h>,#include<sys/stat.h>,#include<fcntl.h>函數(shù)原型:intopen(constchar*pathname,intflags,intperms)參數(shù):pathname:被翻開的文件名〔可包括路徑名如"dev/ttyS0"〕flags:文件翻開方式,O_RDONLY:以只讀方式翻開文件O_WRONLY:以只寫方式翻開文件O_RDWR:以讀寫方式翻開文件O_CREAT:如果改文件不存在,就創(chuàng)立一個(gè)新的文件,并用第三個(gè)參數(shù)為其設(shè)置權(quán)限O_EXCL:如果使用O_CREAT時(shí)文件存在,那么返回錯(cuò)誤消息。這一參數(shù)可測試文件是否存在。此時(shí)open是原子操作,防止多個(gè)進(jìn)程同時(shí)創(chuàng)立同一個(gè)文件O_NOCTTY:使用本參數(shù)時(shí),假設(shè)文件為終端,那么該終端不會(huì)成為調(diào)用open()的那個(gè)進(jìn)程的控制終端

O_TRUNC:假設(shè)文件已經(jīng)存在,那么會(huì)刪除文件中的全部原有數(shù)據(jù),并且設(shè)置文件大小為0

O_APPEND:以添加方式翻開文件,在翻開文件的同時(shí),文件指針指向文件的末尾,即將寫入的數(shù)據(jù)添加到文件的末尾O_NONBLOCK:如果pathname指的是一個(gè)FIFO、一個(gè)塊特殊文件或一個(gè)字符特殊文件,那么此選擇項(xiàng)為此文件的本次翻開操作和后續(xù)的I/O操作設(shè)置非阻塞方式。O_SYNC:使每次write都等到物理I/O操作完成。

O_RSYNC:read等待所有寫入同一區(qū)域的寫操作完成后再進(jìn)行

在open()函數(shù)中,falgs參數(shù)可以通過“|”組合構(gòu)成,但前3個(gè)標(biāo)準(zhǔn)常量〔O_RDONLY,O_WRONLY,和O_RDWR〕不能互相組合。perms:被翻開文件的存取權(quán)限,可以用兩種方法表示,可以用一組宏定義:S_I(R/W/X)(USR/GRP/OTH),其中R/W/X表示讀寫執(zhí)行權(quán)限,USR/GRP/OTH分別表示文件的所有者/文件所屬組/其他用戶,如S_IRUUR|S_IWUUR|S_IXUUR,〔-rex------〕,也可用八進(jìn)制800表示同樣的權(quán)限返回值:成功:返回文件描述符失?。悍祷?1

2.close〔〕函數(shù)功能描述:用于關(guān)閉一個(gè)被翻開的的文件所需頭文件:

#include<unistd.h>函數(shù)原型:intclose(intfd)參數(shù):fd文件描述符函數(shù)返回值:0成功,-1出錯(cuò)3.read〔〕函數(shù)功能描述:從文件讀取數(shù)據(jù)。

所需頭文件:

#include<unistd.h>函數(shù)原型:ssize_tread(intfd,void*buf,size_tcount);參數(shù):

fd:

將要讀取數(shù)據(jù)的文件描述詞。

buf:指緩沖區(qū),即讀取的數(shù)據(jù)會(huì)被放到這個(gè)緩沖區(qū)中去。

count:表示調(diào)用一次read操作,應(yīng)該讀多少數(shù)量的字符。返回值:返回所讀取的字節(jié)數(shù);0〔讀到EOF〕;-1〔出錯(cuò)〕。以下幾種情況會(huì)導(dǎo)致讀取到的字節(jié)數(shù)小于

count:

A.讀取普通文件時(shí),讀到文件末尾還不夠

count字節(jié)。例如:如果文件只有30字節(jié),而我們想讀取100

字節(jié),那么實(shí)際讀到的只有30字節(jié),read函數(shù)返回30。此時(shí)再使用read函數(shù)作用于這個(gè)文件會(huì)導(dǎo)致read返回0。

B.從終端設(shè)備〔terminaldevice〕讀取時(shí),一般情況下每次只能讀取一行。

C.從網(wǎng)絡(luò)讀取時(shí),網(wǎng)絡(luò)緩存可能導(dǎo)致讀取的字節(jié)數(shù)小于count字節(jié)。

D.讀取pipe或者FIFO時(shí),pipe或FIFO里的字節(jié)數(shù)可能小于

count。

E.從面向記錄〔record-oriented〕的設(shè)備讀取時(shí),某些面向記錄的設(shè)備〔如磁帶〕每次最多只能返回一個(gè)記錄。

F.在讀取了局部數(shù)據(jù)時(shí)被信號(hào)中斷。

讀操作始于cfo。在成功返回之前,cfo增加,增量為實(shí)際讀取到的字節(jié)數(shù)。4.write〔〕函數(shù)功能描述:向文件寫入數(shù)據(jù)。

所需頭文件:

#include<unistd.h>函數(shù)原型:ssize_twrite(intfd,void*buf,size_tcount);返回值:寫入文件的字節(jié)數(shù)〔成功〕;-1〔出錯(cuò)〕功能:write函數(shù)向filedes中寫入

count字節(jié)數(shù)據(jù),數(shù)據(jù)來源為buf。返回值一般總是等于count,否那么就是出錯(cuò)了。常見的出錯(cuò)原因是磁盤空間滿了或者超過了文件大小限制。對(duì)于普通文件,寫操作始于cfo。如果翻開文件時(shí)使用了O_APPEND,那么每次寫操作都將數(shù)據(jù)寫入文件末尾。成功寫入后,cfo增加,增量為實(shí)際寫入的字節(jié)數(shù)。

1.lseek〔〕函數(shù)

功能描述:用于在指定的文件描述符中將將文件指針定位到相應(yīng)位置。

所需頭文件:

#include<unistd.h>,#include<sys/types.h>函數(shù)原型:off_tlseek(intfd,off_toffset,intwhence);參數(shù):fd;文件描述符offset:偏移量,每一個(gè)讀寫操作所需要移動(dòng)的距離,單位是字節(jié),可正可負(fù)〔向前移,向后移〕whence:SEEK_SET:當(dāng)前位置為文件的開頭,新位置為偏移量的大小SEEK_CUR:當(dāng)前位置為指針的位置,新位置為當(dāng)前位置加上偏移量SEEK_END:當(dāng)前位置為文件的結(jié)尾,新位置為文件大小加上偏移量的大小返回值:成功:返回當(dāng)前位移失?。悍祷?1函數(shù)實(shí)例:功能是從一個(gè)文件〔源文件〕中讀取最后的10K數(shù)據(jù)復(fù)制到另一個(gè)文件〔目標(biāo)文件〕。實(shí)例中原文件以只讀方式翻開,目標(biāo)文件以只寫方式翻開。假設(shè)目標(biāo)文件不存在,可以創(chuàng)立并設(shè)置權(quán)限為644。#include<stdio.h>#include<stdlib.h>

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

#include<sys/stat.h>

#include<fcntl.h>#defineBUFFER_SIZE1024

//每次讀寫緩存大小,影響運(yùn)行效率

#defineSRC_FILE_NAME"src_file"

//源文件名

#defineDEST_FILE_NAME"dest_file"

//目標(biāo)文件名

#defineOFFSET10240

//復(fù)制的數(shù)據(jù)大小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;

}

現(xiàn)象分析:1.運(yùn)行前如果目錄下沒有src_file,會(huì)出現(xiàn)以下現(xiàn)象

2.有了源文件,但源文件小于10K,會(huì)把源文件的所有數(shù)據(jù)復(fù)制到目標(biāo)文件3.如果源文件大于10K,那么會(huì)把源文件最后的10K復(fù)制到目標(biāo)文件中

利用UTL_FILE包實(shí)現(xiàn)文件I/O操作文件I/O對(duì)于數(shù)據(jù)庫的開發(fā)來說顯得很重要,比方如果數(shù)據(jù)庫中的一局部數(shù)據(jù)來自于磁盤文件,那么就需要使用I/O接口把數(shù)據(jù)導(dǎo)入到數(shù)據(jù)庫中來。在PL/SQL中沒有直接的I/O接口,一般在調(diào)試程序時(shí)可以使用Oracle自帶的DBMS_OUTPUT包的put_line函數(shù)〔即向屏幕進(jìn)行I/O操作〕即可,但是對(duì)于磁盤文件的I/O操作它就無能為力了。其實(shí)Oracle同樣也提供了可以進(jìn)行文件I/O的實(shí)用包-----UTL_FILE包,利用這個(gè)實(shí)用包提供的函數(shù)來實(shí)現(xiàn)對(duì)磁盤的I/O操作。1.準(zhǔn)備工作由于Oracle數(shù)據(jù)庫對(duì)包創(chuàng)立的目錄有一個(gè)平安管理的問題,所以并不是所有的文件目錄能夠被UTL_FILE包所訪問,要更新這種目錄設(shè)置,就得到init.ora里將UTL_FILE_DIR域設(shè)置為*,這樣UTL_FILE包就可以對(duì)所有的目錄文件進(jìn)行訪問了。2.文件I/O的實(shí)施UTL_FILE包提供了很多實(shí)用的函數(shù)來進(jìn)行I/O操作,主要有以下幾個(gè)函數(shù):fopen翻開指定的目錄路徑的文件。get_line獲取指定文件的一行的文本。put_line向指定的文件寫入一行文本。fclose關(guān)閉指定的文件。下面利用這些函數(shù),實(shí)現(xiàn)從文件取數(shù)據(jù),然后將數(shù)據(jù)寫入到相應(yīng)的數(shù)據(jù)庫中。createorreplaceprocedureloadfiledata(p_pathvarchar2,p_filenamevarchar2)as

v_filehandleutl_file.file_type;--定義一個(gè)文件句柄

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);

/*插入數(shù)據(jù)庫操作*/

insertintotest_loadfile

values(v_name,v_addr_jd,v_region);

commit;

endloop;

<<to_end>>

null;

endloadfiledata;

/

3.測試環(huán)境首先要?jiǎng)?chuàng)立一個(gè)目標(biāo)表TEST_LOADFILE,它用來存儲(chǔ)文件中的數(shù)據(jù):CREATETABLETEST_LOADFILE(

NAMEVARCHAR2(100)NOTNULL,

ADDR_JDVARCHAR2(20),

REGIONVARCHAR2(6));然后就可以在sqlplus里輸入如下的代碼并執(zhí)行即可。declare

v_pathvarchar2(200);

v_filenamevarchar2(200);

begin

v_path:='F:';

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

loadfiledata(v_path,v_filename);

end;

/

需要注意的是,這里我的調(diào)試路徑為“f:”地址,如果讀者自己建立實(shí)驗(yàn)環(huán)境,應(yīng)該設(shè)置為的“地址信息”文件的路徑整個(gè)調(diào)試環(huán)境是:效勞器端:UNIX操作系統(tǒng)+Oracle9i數(shù)據(jù)庫效勞器,客戶端:sqlplus,操作系統(tǒng)為WIN2000。4.小結(jié)Oracle本身提供了大量使用的包,如UTL_HTTP包,DBMS_OUTPUT包等,這些包分別封裝了不同的功能,它們使得進(jìn)行大量的應(yīng)用程序開發(fā)的可能,從而拓展了Oracle的功能。linux文件I/O操作之前有介紹過關(guān)于文件的指針和描述符,這次通過一個(gè)練習(xí),熟悉了一下文件的open,close,read,write,sleek,dup等操作,一些主要的考前須知詳見代碼注釋吧。

ps:局部代碼寫的有些齷齪,也和硬要把幾個(gè)函數(shù)都試到有關(guān),應(yīng)該可以用更好的方法。fighting~~~

【功能】命令行輸入三個(gè)參數(shù),將data.dat文件中的內(nèi)容拷貝到data2.dat中,并搜索data2.dat中hello出現(xiàn)的次數(shù),消息打印重定向到dupfile.dat中。

【代碼實(shí)現(xiàn)】#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()

//翻開文件,如果文件不存在,允許按照參數(shù)給定權(quán)限創(chuàng)立,這里文件data.dat為已經(jīng)存在且寫入一定內(nèi)容的。

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';

//防止讀出亂碼影響結(jié)果

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參數(shù)表示每次都是直接用offset做偏移值,即在文件頭的位置+offset;此外SEEK_CUR表示在當(dāng)前位置根底上加offset偏移,SEEK_END表示偏移量為文件大小加offset值。

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

{

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

return1;

}

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

{//可讀到的字符數(shù)小于要搜索的字符串長度,可以跳出

break;

}

else

{

buffer[len]='\0';

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

{

//找到匹配,計(jì)數(shù)+1

flag++;

}//無論是否匹配,offset都應(yīng)該增加1,否那么文件指針一直不變,進(jìn)入死循環(huán)

offset++;

}

}//關(guān)閉標(biāo)準(zhǔn)輸出,并將翻開的文件描述符重定向到標(biāo)準(zhǔn)輸出

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. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論