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