fopen_s _wfopen_s
開啟檔案。 fopen, _wfopen 這兩個版本有安全性增強,如 安全性功能,則在 CRT 中中所述。
errno_t fopen_s(
FILE** pFile,
const char *filename,
const char *mode
);
errno_t _wfopen_s(
FILE** pFile,
const wchar_t *filename,
const wchar_t *mode
);
參數
[out] pFile
要接收指標到開啟的檔案指標的指標。[in] filename
檔名。[in] mode
允許存取的型別。
傳回值
零,如果成功;在失敗時的錯誤碼。 請參閱 errno、 _doserrno、 _sys_errlist 和 _sys_nerr 。如需這些錯誤碼的詳細資訊。
錯誤情況
pFile |
filename |
mode |
傳回值 |
pFile的內容。 |
---|---|---|---|---|
NULL |
any |
any |
EINVAL |
不會變更。 |
any |
NULL |
any |
EINVAL |
不會變更。 |
any |
any |
NULL |
EINVAL |
不會變更。 |
備註
fopen_s 和 _wfopen_s 開啟的檔案無法共用。 如果您需要檔案可共用的,請使用 _fsopen _wfsopen 在適當的共用模式的常數。例如,讀取/寫入共用的 _SH_DENYNO 。
fopen_s 函式會開啟由 filename指定的檔案。 _wfopen_s 是 fopen_s的寬字元版本;對 _wfopen_s 的引數是寬字元字串。 _wfopen_s 和 fopen_s 其餘行為相同。
表示fopen_s 接受表示在檔案系統中執行的路徑;包含對應的網路磁碟機的 UNC 路徑和由 fopen_s 接受,只要執行程式碼的系統對這個共用的存取或對應的網路磁碟機上執行時。 當您建構 fopen_s的路徑時,不要對磁碟、路徑或網路共用的可用性的假設在執行環境。 您可以使用正斜線 (/) 或反斜線 (\) 做為目錄分隔符號在路徑。
這些函式會驗證它們的參數。 如果 pFile、 filename或 mode 為 null 指標,這些函式會產生不正確的參數例外狀況,如 參數驗證中所述。
永遠檢查傳回值的函式是否成功,在您對檔案之前的任何額外作業。 如果發生錯誤,錯誤碼傳回,而這個全域變數 errno 設定。 如需詳細資訊,請參閱errno、 _doserrno、 _sys_errlist 和 _sys_nerr。
Unicode 支援
fopen_s 支援 Unicode 檔案資料流。 若要開啟新的或現有的 Unicode 檔案,請指定預期編碼為 fopen_s的 ccs 旗標:
fopen_s(&fp, "newfile.txt", "rw, ccs=encoding");
encoding 的允許值是 UNICODE、 UTF-8和 UTF-16LE。 如果該值未指定 encoding,則 fopen_s 會使用 ANSI 編碼方式。
如果檔案來讀取或附加已經存在並開啟,檔案中的位元組順序標記 (BOM),如果有的話,決定編碼方式。 BOM 編碼的優先順序高於由 ccs 旗標指定的編碼方式。 只能使用 ccs 項目,當 BOM 不存在時,或者檔案是新的檔案。
注意事項 |
---|
BOM 偵測只能套用至 Unicode 模式下開啟的檔案;透過將 ccs 旗標。 |
下表摘要說明了 fopen_s 以及檔案的位元組順序標記的各種 ccs 旗標的方式。
程式碼使用了以 ccs 旗標和 BOM
ccs 旗標 |
沒有 BOM (或新檔案) |
BOM:UTF-8 |
BOM:UTF-16 |
---|---|---|---|
UNICODE |
UTF-16LE |
UTF-8 |
UTF-16LE |
UTF-8 |
UTF-8 |
UTF-8 |
UTF-16LE |
UTF-16LE |
UTF-16LE |
UTF-8 |
UTF-16LE |
為寫入開啟以 Unicode 編碼方式的檔案有它們會自動寫入的 BOM。
如果 mode 是「a, ccs=<encoding>」, fopen_s 會先嘗試開啟有讀取和寫入的檔案。 如果成功,則函式讀取 BOM 判斷檔案的程式碼;如果不成功,則函式用於檔案的預設編碼方式。 在任何情況下, fopen_s 然後重新開啟具有唯寫存取檔案。 (這適用於 a 不是一種只, a+)。
泛用文字常式對應
TCHAR.H 常式 |
未定義 _UNICODE & _MBCS |
已定義 _MBCS |
已定義 _UNICODE |
---|---|---|---|
_tfopen_s |
fopen_s |
fopen_s |
_wfopen_s |
字串 mode 如下指定要求檔案,這個值的存取。
"r"
開啟進行讀取、。 如果檔案不存在或找不到, fopen_s 呼叫失敗。"w"
開啟撰寫的空檔案。 如果檔案存在,終結它的內容。"a"
撰寫會在檔案 (附加) 結束時,如果沒有移除 EOF 標記將新資料加入檔案。 如果不存在,則會建立檔案。"r+"
用於讀取和寫入開啟。 (檔案必須存在)。"w+"
開啟讀取和寫入的空檔案。 如果檔案存在,終結它的內容。"a+"
用於讀取和附加開啟。 附加的作業包括 EOF 標記的移除,新資料寫入檔案之前,且 EOF 標記還原,在寫入完成之後。 如果不存在,則會建立檔案。
使用 "a" 或 "a+" 存取型別時,在檔案開啟,任何寫入作業可以發生在檔案結尾。 使用 fseek 或 rewind,檔案指標可以重新調整位置,不過,它一定會移回至檔案結尾,在任何寫入作業之前,讓現有資料無法覆寫。
"a" 方法不在附加之前移除 EOF 標記加入至檔案。 在附加之後發生, MS-DOS 型別命令展示資料會附加至檔案的原始 EOF 標記決策和不會只任何資料。 "a+" 方法在附加之前移除 EOF 標記加入至檔案。 在附加之後, MS-DOS 型別順序檔中的所有資料。 "a+" 方法對於附加所使用 CTRL+Z EOF 標記,終端資料流檔案。
當 "r+", 為 "w+", 或 "a+" 存取型別指定時,讀取和寫入允許。 (檔案被視為開啟為「Update」的按鈕)。不過,也就是說,當您從讀取轉換為寫入時,輸入作業必須在 EOF 標記。 如果沒有 EOF,您必須使用介入呼叫到檔案當地語系化函式。 檔案當地語系化函式是 fsetpos、 fseek和 rewind。 當您從文字轉換為讀取時,您必須使用介入呼叫 fflush 或檔案當地語系化函式。
除了上述值之外,下列字元在 mode 中包含的新行字元指定版本模式:
- t
開啟文字 (轉換) 模式。 在此模式下, CTRL+Z 是解譯成輸入的檔案結尾字元。 如果可以在已經開啟來讀取的檔案/與 "a+"的文字 fopen_s ,檢查 CTRL+Z 在檔案結尾,並移除它。 這是可以做到的,因為使用 fseek 和 ftell 會 CTRL+Z 結束檔案內移動,可以讓 fseek 在檔案結尾附近不正確的行為。
此外,在文字模式,重設為一組組合轉譯成在輸入的單一新行字元,,和換行字元轉譯成輸出中重設換行字元的組合。 當 Unicode 資料流 I/O 函式在文字模式 (預設) 下運作,來源或目的資料流假設是多位元組字元序列。 因此, Unicode 資料流輸入函式轉換多位元組字元之寬字元 (就像由 mbtowc 函式的呼叫)。 基於相同的原因, Unicode 資料流輸出函式轉換寬字元對多位元組字元 (就像由 wctomb 函式的呼叫)。
- b
開啟二進位 (未轉譯的) 模式;包含歸位字元和換行字元的轉譯會隱藏。
如果 t 或 b 是 mode不會重新命名,版本模式的預設是由全域變數 _fmode定義的。 如果 t 或 b 前置引數,函式失敗並傳回 NULL。
如需使用文字和二進位模式的詳細資訊以 Unicode 和多位元組資料流 I/O,請參閱 文字和二進位模式檔案 I/O 和 Unicode 文字和二進位模式的資料流 I/O。
c
啟用相關聯之 filename 的做旗標,以便檔案緩衝區的內容直接寫入磁碟,如果呼叫 fflush 或 _flushall 。n
重設相關聯之 filename 的做旗標「no-cache」做。這是預設值。 如果您使用 COMMODE.OBJ,連結您的程式也會覆寫全域做旗標。 全域做旗標預設值為「no-cache」做,除非您使用 COMMODE.OBJ 明確連結您的程式 (請參閱 連結選項)。N
指定檔案沒有由子處理序繼承。S
指定快取進行最佳化,不過,沒有限制,循序存取從磁碟。R
指定快取進行最佳化,不過,沒有限制,隨機存取從磁碟。T
指定檔案如暫存。 可能的話,不會清除至磁碟。D
指定檔案如暫存。 最後,當檔案指標關閉時,會刪除。ccs=ENCODING
指定編碼字元集對這個檔案使用 (UTF-8、UTF-16LE 和 UNICODE)。 如果您想要使用 ANSI 編碼方式,請將此未指定。
用於 fopen_s 和 _fdopen 的 mode 字串的有效字元對應於 _open 和 _sopen的 oflag 引數,如下所示。
在模式字串中的字元 |
_open的對等_sopen/ oflag 值 |
---|---|
a |
通常 _O_WRONLY | _O_CREAT |_O_WRONLY | _O_APPEND (_O_APPEND) |
a+ |
_O_RDWR | _O_APPEND (一般為 _O_RDWR | _O_APPEND | _O_CREAT ) |
r |
_O_RDONLY |
r+ |
_O_RDWR |
w |
通常 _O_WRONLY |_O_WRONLY (_O_CREAT | _O_TRUNC) |
w+ |
_O_RDWR (一般為 _O_RDWR | _O_CREAT | _O_TRUNC) |
b |
_O_BINARY |
t |
_O_TEXT |
c |
None |
n |
None |
S |
_O_SEQUENTIAL |
R |
_O_RANDOM |
T |
_O_SHORTLIVED |
D |
_O_TEMPORARY |
ccs=UNICODE |
_O_WTEXT |
ccs=UTF-8 |
_O_UTF8 |
ccs=UTF-16LE |
_O_UTF16 |
如果您使用 rb 模式,不需要移植程式碼,並預期讀很多檔案並不會如需網路效能,記憶體對應 Win32 檔也可能是選項。
需求
Function |
必要的標頭檔 |
---|---|
fopen_s |
<stdio.h> |
_wfopen_s |
<stdio.h> 或 <wchar.h> |
如需其他相容性資訊,請參閱入門介紹中的 相容性 (Compatibility) 。
程式庫
所有的 C 執行階段程式庫 (C run-time libraries) 版本。
c、 n和 tmode 選項是 fopen_s 和 _fdopen 的 Microsoft 擴充功能,而且不應該使用 ANSI 可攜性所需的位置。
範例
// crt_fopen_s.c
// This program opens two files. It uses
// fclose to close the first file and
// _fcloseall to close all remaining files.
#include <stdio.h>
FILE *stream, *stream2;
int main( void )
{
errno_t err;
// Open for read (will fail if file "crt_fopen_s.c" does not exist)
err = fopen_s( &stream, "crt_fopen_s.c", "r" );
if( err == 0 )
{
printf( "The file 'crt_fopen_s.c' was opened\n" );
}
else
{
printf( "The file 'crt_fopen_s.c' was not opened\n" );
}
// Open for write
err = fopen_s( &stream2, "data2", "w+" );
if( err == 0 )
{
printf( "The file 'data2' was opened\n" );
}
else
{
printf( "The file 'data2' was not opened\n" );
}
// Close stream if it is not NULL
if( stream )
{
err = fclose( stream );
if ( err == 0 )
{
printf( "The file 'crt_fopen_s.c' was closed\n" );
}
else
{
printf( "The file 'crt_fopen_s.c' was not closed\n" );
}
}
// All other files are closed:
int numclosed = _fcloseall( );
printf( "Number of files closed by _fcloseall: %u\n", numclosed );
}
.NET Framework 對等用法
System::IO::FileStream::FileStream