複製鏈接
請複製以下鏈接發送給好友

fopen

鎖定
fopen的函數原型為: FILE *fopen(const char *filename, const char *mode);其功能是使用給定的模式 mode 打開 filename 所指向的文件。文件順利打開後,指向該流的文件指針就會被返回。如果文件打開失敗則返回 NULL,並把錯誤代碼存在 error 中。該函數位於C 標準庫<stdio.h>中。 [1] 
中文名
fopen
外文名
fopen
函數功能
打開一個文件
頭文件
#include <stdio.h>
應    用
C語言

fopenfopen函數語法

fopen函數原型

FILE *fopen(const char *filename, const char *mode);

fopen參數

  • filename-- 這是 C 字符串,包含了要打開的文件名稱。
  • mode-- 這是 C 字符串,包含了文件訪問模式。

fopen功能

使用給定的模式mode打開filename所指向的文件。

fopen返回值

文件順利打開後,指向該流的文件指針就會被返回。如果文件打開失敗則返回 NULL,並把錯誤代碼存在error中。
一般而言,打開文件後會做一些文件讀取或寫入的動作,若打開文件失敗,接下來的讀寫動作也無法順利進行,所以一般在 fopen() 後作錯誤判斷及處理。 [1] 

fopen參數説明

參數mode字符串包含了文件訪問模式,欲打開的文件路徑及文件名,參數 mode 字符串則代表着流形態。
mode 有下列幾種形態字符串:
字符串
説明
r
以只讀方式打開文件,該文件必須存在。
r+
以讀/寫方式打開文件,該文件必須存在。
rb+
以讀/寫方式打開一個二進制文件,只允許讀/寫數據。
rt+
以讀/寫方式打開一個文本文件,允許讀和寫。
w
打開只寫文件,若文件存在則文件長度清為零,即該文件內容會消失;若文件不存在則創建該文件。
w+
打開可讀/寫文件,若文件存在則文件長度清為零,即該文件內容會消失;若文件不存在則創建該文件。
a
以附加的方式打開只寫文件。若文件不存在,則會創建該文件;如果文件存在,則寫入的數據會被加到文件尾後,即文件原先的內容會被保留(EOF 符保留)。
a+
以附加方式打開可讀/寫的文件。若文件不存在,則會創建該文件,如果文件存在,則寫入的數據會被加到文件尾後,即文件原先的內容會被保留(EOF符不保留)。
wb
以只寫方式打開或新建一個二進制文件,只允許寫數據。
wb+
以讀/寫方式打開或新建一個二進制文件,允許讀和寫。
wt+
以讀/寫方式打開或新建一個文本文件,允許讀和寫。
at+
以讀/寫方式打開一個文本文件,允許讀或在文本末追加數據。
ab+
以讀/寫方式打開一個二進制文件,允許讀或在文件末追加數據。
以 x 結尾的模式為獨佔模式,文件已存在或者無法創建(一般是路徑不正確)都會導致 fopen 失敗。文件以操作系統支持的獨佔模式打開。
上述的形態字符串都可以再加一個 b 字符,如 rb、w+b 或 ab+ 等組合,加入 b 字符用來告訴函數庫以二進制模式打開文件。如果不加 b,表示默認加了 t,即 rt、wt,其中 t 表示以文本模式打開文件。由 fopen() 所建立的新文件會具有 S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH(0666) 權限,此文件權限也會參考umask值。
有些 C編譯系統可能不完全提供所有這些功能,有的C版本不用"r+"、"w+"、"a+",而用"rw"、"wr"、"ar"等,讀者注意所用系統的規定。
二進制和文本模式的區別
1、在Windows系統中,文本模式下,文件以"\r\n"代表換行。若以文本模式打開文件,並用 fputs 等函數寫入換行符"\n"時,函數會自動在"\n"前面加上"\r"。即實際寫入文件的是"\r\n"。
2、在類 Unix/Linux 系統中文本模式下,文件以"\n"代表換行。所以 Linux 系統中在文本模式和二進制模式下並無區別。 [1] 
打開方式總結:
各種打開方式主要有三個方面的區別:
1、打開是否為二進制文件,用“b”標識。
2、讀寫的方式,有以下幾種:只讀、只寫、讀寫、追加只寫、追加讀寫這幾種方式。
3、對文件是否必 須存在、以及存在時是清空還是追加會有不同的響應。具體判斷如圖1所示。
圖1 圖1

fopen程序示例

示例一
#include <stdio.h>
#define F_PATH "d:\\myfile\\file.dat"

int main(void)
{
    FILE *fp = NULL; /* 需要注意 */
    fp = fopen(F_PATH, "r");
    if (NULL == fp)
    {
        return -1; /* 要返回錯誤代碼 */
    }
    fclose(fp);
    fp = NULL; /* 需要指向空,否則會指向原打開文件地址 */
    return 0;
}
示例二
#include <stdio.h>
#include <stdlib.h> /* 為了使用exit() */

int main(void)
{
    int i = 0; /* 用於 putchar & getc 的數據接收 */
    char ch = ' ';
    FILE *fp = NULL;
    char fname[50]; /* 用於存放文件名 */
    printf("輸入文件名:");
    scanf("%s", fname);
    fp = fopen(fname, "r"); /* 只供讀取 */
    if (NULL == fp) /* 如果失敗了 */
    {
        printf("錯誤!");
        exit(1); /* 中止程序 */
    }
    while ((ch = getc(fp)) != EOF)
    {
        putchar(ch);
        i ++;
    }
    fclose(fp); /* 關閉文件 */
    fp = NULL; /* 需要指向空,否則會指向原打開文件地址 */
    return 0;
}
注意!初學者往往會犯一個錯誤,即在輸入文件名時不加後綴名,請注意加上!
示例三
#include <stdio.h>
FILE *stream, *stream2;

int main(void)
{
    int numclosed; /* Open for read (will fail if file "crt_fopen.c" does not exist) */
    if ((stream = fopen("crt_fopen.c", "r")) == NULL) /* C4996 */
        //Note: fopen is deprecated; consider using fopen_s instead
        printf("The file `crt_fopen.c' was not opened\n");
    else
        printf("The file `crt_fopen.c' was opened\n"); /* Open for write */
    if ((stream2 = fopen("data2", "w+")) == NULL) /* C4996 */
        printf("The file `data2' was not opened\n");
    else
        printf("The file `data2' was opened\n");
    /* Closes tream if it is not NULL */
    if (stream)
    {
        if (fclose(stream))
        {
            printf("The file `crt_fopen.c' was not closed\n");
        }
    }
    /* All other files are closed: */
    numclosed = _fcloseall();
    printf("Number of files closed by _fcloseall: %u\n", numclosed);
}
示例四
Linux 下的程序示例。
在 / opt / C_lanuage / fopen_fread 新建兩個文本,main.c 和 tmp.txt
tmp.txt:
I Love You Linux----Red Hat Enterprise----夢劇場的記憶
main.c 程序:
#include <stdio.h>
int main(void)
{
    FILE *fp = NULL;
    char tmp[100];
    fp = fopen("/opt/C_lanuage/fopen_fread/tmp.txt", "r");
    if (NULL == fp)
    {
        printf("File open fail!\n");
        return -1;
    }
    fread(tmp, 1, 100, fp);
    printf("%s\n", tmp);
    fclose(fp);
    fp = NULL;
    return 0;
}

編譯加執行
[root@localhost fopen_fread]# gcc - g main.c - o main
[root@localhost fopen_fread]# . / main
I Love You Linux----Red Hat Enterprise----夢劇場的記憶
在文件操作時,需要注意以下幾點問題:
1、在定義文件指針時,要將文件指針指向空;如 FILE *fp = NULL;
2、在文件操作完成後,需要將文件關閉,一定要注意,否則會造成文件所佔用內存泄漏和在下次訪問文件時出現問題。
3、文件關閉後,需要將文件指針指向空,這樣做會防止出現遊離指針,而對整個工程造成不必要的麻煩;如:fp = NULL;

fopen拓展延伸—fopen在PHP中

fopen函數原型

resource fopen ( string filename, string mode, [ bool use_include_path, [resource zcontext]] )

fopen功能

fopen() 函數打開一個文件或 URL。
如果 fopen() 失敗,它將返回 FALSE 並附帶錯誤信息。您可以通過在函數名前面添加一個 '@' 來隱藏錯誤輸出。

fopen應用説明

fopen() 將 filename 指定的名字資源綁定到一個流上。如果 filename 是 "scheme://..." 的格式,則被當成一個 URL,PHP 將搜索協議處理器(也被稱為封裝協議)來處理此模式。如果該協議尚未註冊封裝協議,PHP 將發出一條消息來幫助檢查腳本中潛在的問題並將 filename 當成一個普通的文件名繼續執行下去。
如果 PHP 認為 filename 指定的是一個本地文件,將嘗試在該文件上打開一個流。該文件必須是 PHP 可以訪問的,因此需要確認文件訪問權限允許該訪問。如果激活了 安全模式 或者 open_basedir 則會應用進一步的限制。 [2] 

fopen應用示例

<?php
$handle=fopen("/home/rasmus/file.txt","r");
$handle=fopen("/home/rasmus/file.gif","wb");
?>

fopen拓展延伸—MATLAB函數

在matlab中,fopen也是一個打開文件的函數。在matlab的命令窗口中輸入doc fopen或者help fopen就可以獲得該函數的幫助信息。 [3] 

fopen調用格式

fileID = fopen(filename)
fileID = fopen(filename, permission)
fileID = fopen(filename, permission, machineformat)
fileID = fopen(filename, permission, machineformat, encoding)
[fileID, message]= fopen(filename, ...)
fIDs = fopen('all')
[filename, permission, machineformat, encoding]= fopen(fileID)
各種調用格式詳情請參閲MATLAB幫助文檔。

fopen程序示例

% MATLAB: fopen()函數的使用
clcfileID = fopen('Test.txt', 'w');
if fileID == -1disp('fopen failed.');
return;
elsedisp('fopen succeed.');
endStr = 'It is just a test. By mayadong7349';
fprintf(fileID, '%s', Str);
% Caution:disp('Now, I''d like to type the file.');
type('Test.txt');fclose(fileID);

程序首先向文件寫入字符串,然後通過type打印在屏幕上。
這裏需要注意的是,如果字符串內有單撇號(')要用兩個單撇號表示一個單撇號。
在Oracle中
Oracle提供的文件操作包UTL_FILE包中的UTL_FILE.FOPEN負責打開一個文件。
UTL_FILE.FOPEN(location in varchar2, filename in varchar2, open_mode in varchar2) return FILE_TYPE;
Location 是路徑參數,
FILENAME 是文件名,
OPEN_MODE是打開模式,'R'是讀文本,'W'是寫文本,'A'是附加文本,參數不分大小寫,如果指定'A'但是文件不存在,它會用'W'先創建出來,'W'有覆蓋的功能;
其中的location並不能簡單的指定為'D:\temp'等路徑,要建立一個DIRECTORY變量並付給權限(必須以DBA身份登錄):
create or replace directory D_OUTPUT as 'D:\TEMP';
grant read,write on directory D_OUTPUT to testdb;
GRANT EXECUTE ON utl_file TO testdb;
之後就可以用UTL_FILE包建立文件了 :
V_FILE UTL_FILE.FILE_TYPE;
V_FILE := UTL_FILE.FOPEN('D_OUTPUT', 'Data.txt', 'w');
參考資料
  • 1.    張權. Objective-C函數速查實例手冊 :人民郵電出版社,2014.2
  • 2.    列旭松,陳文 .PHP核心技術與最佳實踐(第2版): 機械工業出版社 ,2018.9
  • 3.    張志湧 , 楊祖櫻 . MATLAB教程 : 北京航空航天大學出版社,2015.1