不帶緩存的文件IO操作_第1頁
不帶緩存的文件IO操作_第2頁
不帶緩存的文件IO操作_第3頁
不帶緩存的文件IO操作_第4頁
不帶緩存的文件IO操作_第5頁
已閱讀5頁,還剩8頁未讀, 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

1、lseek不帶緩存的文件I/O操作本節(jié)主要介紹不帶緩存的文件I/O操作,主要用到5個函數(shù):open、read、write、和close。這里的不帶緩存是指每一個函數(shù)都只調(diào)用系統(tǒng)中的一個函數(shù)。這些函數(shù)雖然不是ANSIC的組成部分,但是是POSIX的組成部分。631open和close(1)open和close函數(shù)說明open函數(shù)是用于打開或創(chuàng)建文件,在打開或創(chuàng)建文件時可以指定文件的屬性及用戶的權(quán)限等各種參數(shù)。close函數(shù)是用于關(guān)閉一個打開文件。當(dāng)一個進程終止時,它所有已打開的文件都由內(nèi)核自動關(guān)閉,很多程序都使用這一功能而不顯示地關(guān)閉一個文件。(2)open和close函數(shù)格式open函數(shù)的語法

2、格式如表6.1所示。表6.1open函數(shù)語法要點所需頭文件#include/提供類型pid_t的定義#include#include續(xù)表函數(shù)原型intopen(constchar*pathname,flags,intperms)pathname被打開的文件名(可包括路徑名)O_RDONLY:只讀方式打開文件O_WRONLY:可寫方式打開文件O_RDWR:讀寫方式打開文件O_CREAT:如果該文件不存在,就創(chuàng)建一個新的文件,并用第三個參數(shù)為其設(shè)置權(quán)限O_EXCL:如果使用O_CREAT時文件存在,則可返回錯誤消息。這一參數(shù)可測試文件是否存在O_NOCTTY:使用本參數(shù)時,如文件為終端,那么終端不

3、可以作為調(diào)用open()系統(tǒng)調(diào)用的那個進程的控制終端O_TRUNC:如文件已經(jīng)存在,并且以只讀或只寫成功打開,那么會先全部刪除文件中原有數(shù)據(jù)flag:文件打開的方式O+APPEND:以添加方式打開文件,在打開文件的同時,文件指針指向文件的末尾函數(shù)傳入值perms被打開文件的存取權(quán)限,為8進制表示法函數(shù)返回值成功:返回文件描述符失?。?在open函數(shù)中,flag參數(shù)可通過“|”組合構(gòu)成,但前3個函數(shù)不能相互組合。perms是文件的存取權(quán)限,采用8進制表示法,相關(guān)內(nèi)容讀者可參見第2章。close函數(shù)的語法格式如下表6.2所示。表6.2close函數(shù)語法要點嵌入式Linux應(yīng)用程序開發(fā)詳解第6章、文

4、件IO編程所需頭文件#include函數(shù)原型intclose(intfd)函數(shù)輸入值fd:文件描述符函數(shù)返回值0:成功1:出錯open和close函數(shù)使用實例下面實例中的open函數(shù)帶有3個flag參數(shù):O_CREAT、O_TRUNC和O_WRONLY,這樣就可以對不同的情況指定相應(yīng)的處理方法。另外,這里對該文件的權(quán)限設(shè)置為0600。其丿、源碼如下所示:/*open.c*/#include#include#include#include#include#includeintmain(void)intfd;/*調(diào)用open函數(shù),以可讀寫的方式打開,注意選項可以用“|”符號連接*/if(fd=op

5、en(/tmp/hello.c,O_CREAT|O_TRUNC|O_WRONLY,0600)0)perror(open:);exit(1);elseprintf(Openfile:hello.c%dn,fd);if(close(fd)0)perror(close:);exit(1);elseprintf(C);exit(0);root(none)1#./openOpenfile:hello.c3Closehello.croot(none)tmp#ls-l|grephello.c-rw1rootroot0Dec400:59hello.c經(jīng)過交叉編譯后,將文件下載到目標(biāo)板,則該可執(zhí)行文件運行后就能

6、在目錄/tmp下新建一個hello.c的文件,其權(quán)限為0600。注意open函數(shù)返回的文件描述符一定是最小的未用文件描述符。由于一個進程在啟動時自動打開了0、1、2三個文件描述符,因此,該文件運行結(jié)果中返回的文件描述符為3。讀者可以嘗試在調(diào)用open函數(shù)之前,加依據(jù)close(O),則此后在open函數(shù)時返回的文件描述符為0(若關(guān)閉文件描述符1,則在執(zhí)行時會由于沒有標(biāo)準(zhǔn)輸出文件而無法輸出)。632read、write和Iseekread、write和Iseek函數(shù)作用read函數(shù)是用于將指定的文件描述符中讀出數(shù)據(jù)。當(dāng)從終端設(shè)備文件中讀出數(shù)據(jù)時,通常一次最多讀一行。write函數(shù)是用于向打開的文

7、件寫數(shù)據(jù),寫操作從文件的當(dāng)前位移量處開始。若磁盤已滿或超出該文件的長度,則write函數(shù)返回失敗。Iseek函數(shù)是用于在指定的文件描述符中將文件指針定位到相應(yīng)的位置。read和write函數(shù)格式read函數(shù)的語法格式如下表6.3所示。表6.3read函數(shù)語法要點所需頭文件#incIude函數(shù)原型ssize_tread(intfd,void*buf,size_tcount)fd:文件描述符函數(shù)傳入值buf:指定存儲器讀出數(shù)據(jù)的緩沖區(qū)count:指定讀出的字節(jié)數(shù)函數(shù)返回值成功:讀到的字節(jié)數(shù)0:已到達文件尾1:出錯在讀普通文件時,若讀到要求的字節(jié)數(shù)之前已到達文件的尾部,則返回的字節(jié)數(shù)會小于希望讀出的

8、字節(jié)數(shù)。write函數(shù)的語法格式如下表6.4所示。表6.4write函數(shù)語法要點所需頭文件#incIude函數(shù)原型ssize_twrite(intfd,void*buf,size_tcount)嵌入式Linux應(yīng)用程序開發(fā)詳解第6章、文件IO編程fd:文件描述符函數(shù)傳入值buf:指定存儲器寫入數(shù)據(jù)的緩沖區(qū)count:指定讀出的字節(jié)數(shù)函數(shù)返回值成功:已寫的字節(jié)數(shù)1:出錯在寫普通文件時,寫操作從文件的當(dāng)前位移處開始。Iseek函數(shù)的語法格式如下表6.5所示。表6.5lseek函數(shù)語法要點所需頭文件#incIude#incIude函數(shù)原型off_tIseek(intfd,off_toffset,in

9、twhence)fd:文件描述符函數(shù)傳入值offset:偏移量,每一讀寫操作所需要移動的距離,單位是字節(jié)的數(shù)量,可正可負(向前移,向后移)續(xù)表SEEK_SET:當(dāng)前位置為文件的開頭,新位置為偏移量的大小SEEK_CUR:當(dāng)前位置為文件指針的位置,新位置為當(dāng)前位置加上偏移量whence:當(dāng)前位置的基點SEEK_END:當(dāng)前位置為文件的結(jié)尾,新位置為文件的大小加上偏移量的大小函數(shù)返回值成功:文件的當(dāng)前位移1:出錯(3)函數(shù)使用實例該示例程序首先打開上一節(jié)中創(chuàng)建的文件,然后對此文件進行讀寫操作(記得要將文件打開屬性改為可讀寫,將文件權(quán)限也做相應(yīng)更改)。接著,寫入“HeIIo!Imwritingtot

10、hisfiIe!”,10此時文件指針位于文件尾部。接著在使用Iseek函數(shù)將文件指針移到文件開始處,并讀出個字節(jié)并將其打印出來。程序源代碼如下所示:/*write.c*/#incIude#incIude#incIude#incIude#incIude#incIude#incIude#defineMAXSIZEintmain(void)inti,fd,size,Ien;char*buf=HeIIo!ImwritingtothisfiIe!;charbuf_r10;len=strlen(buf);/*首先調(diào)用open函數(shù),并指定相應(yīng)的權(quán)限*/if(fd=open(/tmp/hello.c,O_CR

11、EAT|O_TRUNC|O_RDWR,0666)0)perror(open:);exit(1);elseprintf(openfile:hello.c%dn,fd);/*調(diào)用write函數(shù),將buf中的內(nèi)容寫入到打開的文件中*/if(size=write(fd,buf,len)0)perror(write:);exit(1);elseprintf(Write:%sn,buf);/*調(diào)用Isseek函數(shù)將文件指針移到文件起始,并讀出文件中的10個字節(jié)*/lseek(fd,0,SEEK_SET);if(size=read(fd,buf_r,10)0)perror(read:);exit(1);eI

12、seprintf(readformfiIe:%sn,buf_r);if(cIose(fd)0)perror(cIose:);exit(1);eIseprintf(CIoseheII);exit(0);root(none)1#./writeopenfiIe:heIIo.c3嵌入式Linux應(yīng)用程序開發(fā)詳解第6章、文件IO編程Write:HeIIo!ImwritingtothisfiIe!readformfiIe:HeIIo!ImCIoseheIIo.croot(none)1#cat/tmp/heIIo.cHeIIo!ImwritingtothisfiIe!6.3.3fcntI(1)fcntI函數(shù)

13、說明前面的這5個基本函數(shù)實現(xiàn)了文件的打開、讀寫等基本操作,這一節(jié)將討論的是,在文件已經(jīng)共享的情況下如何操作,也就是當(dāng)多個用戶共同使用、操作一個文件的情況,這時,Linux通常采用的方法是給文件上鎖,來避免共享的資源產(chǎn)生競爭的狀態(tài)。文件鎖包括建議性鎖和強制性鎖。建議性鎖要求每個上鎖文件的進程都要檢查是否有鎖存在,并且尊重已有的鎖。在一般情況下,內(nèi)核和系統(tǒng)都不使用建議性鎖。強制性鎖是由內(nèi)核執(zhí)行的鎖,當(dāng)一個文件被上鎖進行寫入操作的時候,內(nèi)核將阻止其他任何文件對其進行讀寫操作。采用強制性鎖對性能的影響很大,每次讀寫操作都必須檢查是否有鎖存在。在Linux中,實現(xiàn)文件上鎖的函數(shù)有l(wèi)ock和fcntl,其

14、中flock用于對文件施加建議性鎖,而fcntl不僅可以施加建議性鎖,還可以施加強制鎖。同時,fcntl還能對文件的某一記錄進行上鎖,也就是記錄鎖。記錄鎖又可分為讀取鎖和寫入鎖,其中讀取鎖又稱為共享鎖,它能夠使多個進程都能在文件的同一部分建立讀取鎖。而寫入鎖又稱為排斥鎖,在任何時刻只能有一個進程在文件的某個部分上建立寫入鎖。當(dāng)然,在文件的同一部分不能同時建立讀取鎖和寫入鎖。注意fcntl是一個非常通用的函數(shù),它還可以改變文件進程各方面的屬性,在本節(jié)中,主要介紹它建立記錄鎖的方法,關(guān)于它其他用戶感興趣的讀者可以參看fcntl手冊。(2)fcntl函數(shù)格式用于建立記錄鎖的fcntl函數(shù)格式如表6.

15、6所示。表6.6fcntl函數(shù)語法要點所需頭文件#include#include#include函數(shù)原型intfcnt1(intfd,intcmd,structflock*lock)fd:文件描述符F_DUPFD:復(fù)制文件描述符F_GETFD:獲得fd的close-on-exec標(biāo)志,若標(biāo)志未設(shè)置,則文件經(jīng)過exec函數(shù)之后仍保持打開狀態(tài)F_SETFD:設(shè)置close-on-exec標(biāo)志,該標(biāo)志以參數(shù)arg的FD_CLOEXEC位決定F_GETFL:得到open設(shè)置的標(biāo)志函數(shù)傳入值cmdF_SETFL:改變open設(shè)置的標(biāo)志F_GETFK:根據(jù)lock描述,決定是否上文件鎖F_SETFK:設(shè)置

16、lock描述的文件鎖F_SETLKW:這是F_SETLK的阻塞版本(命令名中的W表示等待(wait)如果存在其他鎖,則調(diào)用進程睡眠;如果捕捉到信號則睡眠中斷F_GETOWN:檢索將收到SIGIO和SIGURG信號的進程號或進程組號F_SETOWN:設(shè)置進程號或進程組號Lock:結(jié)構(gòu)為flock,設(shè)置記錄鎖的具體狀態(tài),后面會詳細說明函數(shù)返回值成功:01:出錯這里,lock的結(jié)構(gòu)如下所示:Structflockshortl_type;off_tl_start;shortl_whence;off_tl_len;pid_tl_pid;lock結(jié)構(gòu)中每個變量的取值含義如表6.7所示。表6.7lock結(jié)構(gòu)

17、變量取值F_RDLCK:讀取鎖(共享鎖)l_typeF_WRLCK:寫入鎖(排斥鎖)F_UNLCK:解鎖l_stat相對位移量(字節(jié))SEEK_SET:當(dāng)前位置為文件的開頭,新位置為偏移量的大小SEEK_CUR:當(dāng)前位置為文件指針的位置,新位置為當(dāng)前位置加上偏移量l_whence:相對位移量的起點(同lseek的whence)。SEEK_END:當(dāng)前位置為文件的結(jié)尾,新位置為文件的大小加上偏移量的大小l_len加鎖區(qū)域的長度小技巧為加鎖整個文件,通常的方法是將l_start說明為0,l_whence說明為SEEK_SET,l_len說明為0。(3)fcntl使用實例下面首先給出了使用fcntl

18、函數(shù)的文件記錄鎖函數(shù)。在該函數(shù)中,首先給flock結(jié)構(gòu)體的對應(yīng)位賦予相應(yīng)的值。接著使用兩次fcntl函數(shù)分別用于給相關(guān)文件上鎖和判斷文件是否可以上鎖,這里用到的cmd值分別為F_SETLK和F_GETLK。這個函數(shù)的源代碼如下所示:嵌入式Linux應(yīng)用程序開發(fā)詳解第6章、文件IO編程/*lock_set函數(shù)*/voidlock_set(intfd,inttype)structflocklock;lock.l_whence=SEEK_SET;賦值lock結(jié)構(gòu)體lock.l_start=0;lock.l_len=0;while(1)lock.l_type=type;/*根據(jù)不同的type值給文件上

19、鎖或解鎖*/if(fcntl(fd,F_SETLK,&lock)=0)if(lock.l_type=F_RDLCK)printf(readlocksetby%dn,getpid();elseif(lock.l_type=F_WRLCK)printf(writelocksetby%dn,getpid();elseif(lock.l_type=F_UNLCK)printf(releaselockby%dn,getpid();return;/*判斷文件是否可以上鎖*/fcntl(fd,F_GETLK,&lock);/*判斷文件不能上鎖的原因*/if(lock.l_type!=F_UNLCK)/*/該

20、文件已有寫入鎖*/if(lock.l_type=F_RDLCK)printf(readlockalreadysetby%dn,lock.l_pid);/*該文件已有讀取鎖*/elseif(lock.l_type=F_WRLCK)printf(writelockalreadysetby%dn,lock.l_pid);getchar();hello文件,之后對其上寫入鎖,下面的實例是測試文件的寫入鎖,這里首先創(chuàng)建了一個最后釋放寫入鎖。代碼如下所示:/*fcntl_write.c測試文件寫入鎖主函數(shù)部分*/#include#include#include#include#include#includ

21、eintmain(void)intfd;/*首先打開文件*/fd=open(hello,O_RDWR|O_CREAT,0666);if(fd0)perror(open);exit(1);/*給文件上寫入鎖*/lock_set(fd,F_WRLCK);getchar();/*給文件接鎖*/lock_set(fd,F_UNLCK);getchar();close(fd);exit(0);為了能夠使用多個終端,更好地顯示寫入鎖的作用,本實例主要在PC機上測試,讀者可將其交叉編譯,下載到目標(biāo)板上運行。下面是在PC機上的運行結(jié)果。為了使程序有較大的靈活性,筆者采用文件上鎖后由用戶鍵入一任意鍵使程序繼續(xù)運

22、行。建議讀者開啟兩個終端,并且在兩個終端上同時運行該程序,以達到多個進程操作一個文件的效果。在這里,筆者首先運行終端一,請讀者注意終端二中的第一句。終端一:rootlocalhostfile#./fcntl_writewritelocksetby4994releaselockby4994終端二:rootlocalhostfile#./fcntl_writewritelockalreadysetby4994嵌入式Linux應(yīng)用程序開發(fā)詳解第6章、文件IO編程writelocksetby4997releaselockby4997由此可見,寫入鎖為互斥鎖,一個時刻只能有一個寫入鎖存在。接下來的程序是

23、測試文件的讀取鎖,原理同上面的程序一樣。/*fcntl_read.c測試文件讀取鎖主函數(shù)部分*/#include#include#include#include#include#includeintmain(void)intfd;fd=open(hello,O_RDWR|O_CREAT,0666);if(fd0)perror(open);exit(1);/*給文件上讀取鎖*/lock_set(fd,F_RDLCK);getchar();/*給文件接鎖*/lock_set(fd,F_UNLCK);getchar();close(fd);exit(0);同樣開啟兩個終端,并首先啟動終端一上的程序,

24、其運行結(jié)果如下所示:終端一:rootlocalhostfile#./fcntl2readlocksetby5009releaselockby5009終端二:rootlocalhostfile#./fcntl2readlocksetby5010releaselockby5010讀者可以將此結(jié)果與寫入鎖的運行結(jié)果相比較,可以看出,讀取鎖為共享鎖,當(dāng)進程5009已設(shè)定讀取鎖后,進程5010還可以設(shè)置讀取鎖。思考如果在一個終端上運行設(shè)置讀取鎖,則在另一個終端上運行設(shè)置寫入鎖,會有什么結(jié)果呢?6.3.4selectselect函數(shù)說明前面的fcntl函數(shù)解決了文件的共享問題,接下來該處理I/O復(fù)用的情況

25、了。總的來說,I/O處理的模型有5種。阻塞I/O模型:在這種模型下,若所調(diào)用的I/O函數(shù)沒有完成相關(guān)的功能就會使進程掛起,直到相關(guān)數(shù)據(jù)到才會出錯返回。如常見對管道設(shè)備、終端設(shè)備和網(wǎng)絡(luò)設(shè)備進行讀寫時經(jīng)常會出現(xiàn)這種情況。非阻塞模型:在這種模型下,當(dāng)請求的I/O操作不能完成時,則不讓進程睡眠,而且返回一個錯誤。非阻塞I/O使用戶可以調(diào)用不會永遠阻塞的I/O操作,如open、write和read。如果該操作不能完成,則會立即出錯返回,且表示該I/O如果該操作繼續(xù)執(zhí)行就會阻塞。I/O多路轉(zhuǎn)接模型:在這種模型下,如果請求的I/O操作阻塞,且它不是真正阻塞I/O,而是讓其中的一個函數(shù)等待,在這期間,I/O還

26、能進行其他操作。如本節(jié)要介紹的select函數(shù)和poll函數(shù),就是屬于這種模型。信號驅(qū)動I/O模型:在這種模型下,通過安裝一個信號處理程序,系統(tǒng)可以自動捕獲特定信號的到來,從而啟動I/O。這是由內(nèi)核通知用戶何時可以啟動一個I/O操作決定的。異步I/O模型:在這種模型下,當(dāng)一個描述符已準(zhǔn)備好,可以啟動I/O時,進程會通知內(nèi)核?,F(xiàn)在,并不是所有的系統(tǒng)都支持這種模型??梢钥吹?,select的I/O多路轉(zhuǎn)接模型是處理I/O復(fù)用的一個高效的方法。它可以具體設(shè)置每一個所關(guān)心的文件描述符的條件、希望等待的時間等,從select函數(shù)返回時,內(nèi)核會通知用戶已準(zhǔn)備好的文件描述符的數(shù)量、已準(zhǔn)備好的條件等。通過使用s

27、elect返回值,就可以調(diào)用相應(yīng)的I/O處理函數(shù)了。select函數(shù)格式Select函數(shù)的語法格式如表6.8所示。表6.8fcntl函數(shù)語法要點所需頭文件#include#include嵌入式Linux應(yīng)用程序開發(fā)詳解第6章、文件IO編程#include函數(shù)原型intselect(intnumfds,fd_set*readfds,fd_set*writefds,fd_set*exeptfds,structtimeval*timeout)numfds:需要檢查的號碼最高的文件描述符加1readfds:由select()監(jiān)視的讀文件描述符集合writefds:由select()監(jiān)視的寫文件描述符集

28、合exeptfds:由select()監(jiān)視的異常處理文件描述符集合NULL:永遠等待,直到捕捉到信號或文件描述符已準(zhǔn)備好為止具體值:structtimeval類型的指針,若等待為timeout時間還沒有文件描符準(zhǔn)備好,就立即返回函數(shù)傳入值timeout0:從不等待,測試所有指定的描述符并立即返回函數(shù)返回值成功:準(zhǔn)備好的文件描述符1:出錯思考請讀者考慮一下如何確定最高的文件描述符?可以看到,select函數(shù)根據(jù)希望進行的文件操作對文件描述符進行了分類處理,這里,對文件描述符的處理主要涉及到4個宏函數(shù),如表6.9所示。表6.9select文件描述符處理函數(shù)FD_ZERO(fd_set*set)清除

29、一個文件描述符集FD_SET(intfd,fd_set*set)將一個文件描述符加入文件描述符集中FD_CLR(intfd,fd_set*set)將一個文件描述符從文件描述符集中清除FD_ISSET(intfd,fd_set*set)測試該集中的一個給定位是否有變化一般來說,在使用select函數(shù)之前,首先使用FD_ZERO和FD_SET來初始化文件描述符集,在使用了select函數(shù)時,可循環(huán)使用FD_ISSET測試描述符集,在執(zhí)行完對相關(guān)后文件描述符后,使用FD_CLR來清楚描述符集。另外,select函數(shù)中的timeout是一個structtimeval類型的指針,該結(jié)構(gòu)體如下所示:str

30、ucttimevallongtv_sec;/*second*/longtv_unsec;/*andmicroseconds*/可以看到,這個時間結(jié)構(gòu)體的精確度可以設(shè)置到微秒級,這對于大多數(shù)的應(yīng)用而言已經(jīng)足夠了。使用實例由于Select函數(shù)多用于I/O操作可能會阻塞的情況下,而對于可能會有阻塞I/O的管道、網(wǎng)絡(luò)編程,本書到現(xiàn)在為止還沒有涉及。因此,本例主要表現(xiàn)了如何使用select函數(shù),而其中的I/O操作是不會阻塞的。本實例中主要實現(xiàn)將文件hello1里的內(nèi)容讀出,并將此內(nèi)容每隔10s寫入hello2中去。在這里建立了兩個描述符集,其中一個描述符集inset1是用于讀取文件內(nèi)容,另一個描述符集i

31、nset2是用于寫入文件的。兩個文件描述符fdsO和fds1分別指向這一文件描述符。在首先初始化完各文件描述符集之后,就開始了循環(huán)測試這兩個文件描述符是否可讀寫,由于在這里沒有阻塞,所以文件描述符處于準(zhǔn)備就緒的狀態(tài)。這時,就分別對文件描述符fds0和fsd1進行讀寫操作。該程序的流程圖如圖6.2所示。/*select.c*/#include#include#include#include#includeintmain(void)intfds2;charbuf7;inti,rc,maxfd;fd_setinset1,inset2;structtimevaltv;/*首先按一定的權(quán)限打開hello1文件*/if(fds0=

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論