打开流 fopen 、freopen和fdopen函数
打開流?fopen?、freopen和fdopen函數(shù)
轉(zhuǎn)載 2015-12-21 14:13:07
fopen?、freopen和fdopen函數(shù)作用都是打開一個標準I/O流的,但是它們有一些略微的差別。從函數(shù)原型、函數(shù)描述、特殊用法。
?
?一、函數(shù)原型
FILE *fopen(const char *restrict pathname, char *restrict type);
FILE *fdopen(int fd, const char *type);
FILE *freopen(const char *restrict pathname,const char *restrict type,FILE *restrict fp);
返回值,若成功,返回文件指針,若失敗,返回NULL
?
mode?參數(shù)類型
?━━━━━━━━━━━━━━━━━━━━━━━━━━━━
????字符??????????????含義
────────────────────────────
??? "r"???????????打開文字文件只讀
??? "w"???????????創(chuàng)建文字文件只寫
??? "a"???????????增補,?如果文件不存在則創(chuàng)建一個
??? "r+"??????????打開一個文字文件讀/寫
??? "w+"??????????創(chuàng)建一個文字文件讀/寫
??? "a+"??????????打開或創(chuàng)建一個文件增補
??? "b"???????????二進制文件(可以和上面每一項合用)
??? "t"???????????文這文件(默認項)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━
?文件使用方式? 意?義
?“rt” ???只讀打開一個文本文件,只允許讀數(shù)據(jù)
“wt” 只寫打開或建立一個文本文件,只允許寫數(shù)據(jù)
?“at” 追加打開一個文本文件,并在文件末尾寫數(shù)據(jù)
?“rb” 只讀打開一個二進制文件,只允許讀數(shù)據(jù)
?“wb” 只寫打開或建立一個二進制文件,只允許寫數(shù)據(jù)
?“ab”? 追加打開一個二進制文件,并在文件末尾寫數(shù)據(jù)
?“rt+” 讀寫打開一個文本文件,允許讀和寫
?“wt+” 讀寫打開或建立一個文本文件,允許讀寫
?“at+” 讀寫打開一個文本文件,允許讀,或在文件末追加數(shù)?據(jù)
?“rb+” 讀寫打開一個二進制文件,允許讀和寫
?“wb+” 讀寫打開或建立一個二進制文件,允許讀和寫
?“ab+”????讀寫打開一個二進制文件,允許讀,或在文件末追加數(shù)據(jù)
二、函數(shù)描述
1、fopen函數(shù):打開路徑名為pathname的一個指定的文件
2、fdopen函數(shù):打開已存在的文件描述符,使標準I/O流與該文件相結合。主要用于fopen不能打開的特殊文件(如管道和網(wǎng)路通信等),這時必須先調(diào)用設備專用函數(shù)以獲得一個文件描述符,然后在用fdopen使一個標準I/O與該文件描述符相結合。
3、Freopen函數(shù):在指定的流上打開一個指定的文件,如若該流已經(jīng)打開,則先關閉該流。若該流已經(jīng)定向,則使用freopen清除該定向。簡單的說可以利用freopen函數(shù)重定向。此函數(shù)一般用于將一個指定的文件代開為一個預定義的流:stdout,stdin,stderr。可以利用freopen將標準流沖定向。不要在程序的一開始就使用freopen。因為標準輸出流(標準輸入流和標準錯誤輸出流)是常量,是不可再分配文件描述符的。
三、特殊用法
1、fopen
在指定w或a類型創(chuàng)建一個新文件時,無法是么該文件的訪問權限位,所以在mode參數(shù)?中不能有r類型。
2、fdopen
(1)在man手冊中指出fdopen中的mode參數(shù)必須與fd原先的mode參數(shù)相匹配。這就是說這時的mode參數(shù)是原先mode參數(shù)的子集。否則會發(fā)生段錯誤。eg
#include
#include
#include
#include
//fdopen 中的mode的參數(shù)必須與參數(shù)fd的原先的讀寫權限相匹配
//參數(shù)mode 是fd原先讀寫權限的子集
int main(void)
{
? ? int fd = -1;
? ? int set = -1; ??
? ? FILE *fp;
? ? //fd = open("./text", O_RDWR | O_APPEND);//no
? ? fd = open("./text", O_WRONLY | O_APPEND);//ok
? ? //fd = open("./text", O_RDONLY | O_APPEND);//no
? ??
? ? write(fd, "text", strlen("text"));
? ? printf("22222\n");
? ? fp = fdopen(fd, "w");
? ? set = ftell(fp);
? ? printf("11111\n");
? ? write(fileno(fp), "qwer", strlen("qwer"));
? ? printf("set = %d\n", set);
? ? exit(0);
}
?(2)在man手冊中指出fdopen返回的文件指針的偏移量與參數(shù)文件描述符fd一致。eg:
#include
#include
#include
#include
#include
//fdopen 返回的fp的文件偏移量是 參數(shù)fd的偏移量。
int main(void)
{
? ? int fd = -1;
? ? int set = -1; ??
? ? FILE *fp;
? ? fd = open("./text", O_RDONLY);
? ? lseek(fd, 0, SEEK_END);
? ? fp = fdopen(fd, "r");
? ? set = ftell(fp);
? ? ?printf("set = %d\n", set);
? ??exit(0);
}
(3)把原先error和end-of-file標志位清除,所以這時fdopen中的參數(shù)type為”w”或”w+”,不會造成截斷文件長度。也就是說不會從文件開頭寫,會追加到現(xiàn)在偏移量之后。eg:
?#include
#include
#include
#include
#include
//因為在使用fdopen時,已經(jīng)把error和end-of-file標志位清除了,所以"w"和"w+"不會截斷文件,新寫入的數(shù)據(jù)會追加原先文件的結尾。
int main(void)
{
? ? int fd = -1;
? ? int set = -1; ??
? ? FILE *fp;
? ? fd = open("./text", O_WRONLY);
? ? lseek(fd, 0, SEEK_END);
? ? fp = fdopen(fd, "w");
? ? write(fileno(fp), "fdopen", strlen("fdopen"));
? ? set = ftell(fp);
? ? printf("set = %d\n", set);
? ? exit(0);
}
?
3、freopen重定向,如果這個流(參數(shù)fp指向的流)是打開的,則這個流將關閉。所以重新使用這個流時得重新打開。但這個流是標準輸入/輸出/錯誤輸出流時,在調(diào)用freopen后重新打開將會比較麻煩。要借助于fgetpos/fsetpos和dup/dup2函數(shù)。下一遍詳細介紹。
?
總結
以上是生活随笔為你收集整理的打开流 fopen 、freopen和fdopen函数的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 文件内存映射mmap解决大文件快速读写问
- 下一篇: 乐高无限无法连接到服务器,乐高无限近期热