Share via


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 
);

參數

  • [] outpFile
    檔案指標會接收到開啟的檔案指標的指標。

  • [in]filename
    檔名。

  • [in]mode
    許可的存取類型。

傳回值

如果成功 ;,零 在失敗的錯誤碼。 請參閱errno、_doserrno、_sys_errlist 和 _sys_nerr如需有關這些錯誤碼。

錯誤條件

pFile

filename

mode

傳回值

內容pFile

NULL

任何

任何

EINVAL

未變更

任何

NULL

任何

EINVAL

未變更

任何

任何

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 檔,請傳遞ccs旗標,指定您想要的編碼, fopen_s:

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旗標。

下表摘要模式的各種ccs旗標,指定給 fopen_s,以及在檔案中的位元組順序標記。

編碼方式使用根據 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+"指定存取類型、 允許讀取和寫入。 (該檔案就稱為屬於開啟以 「 更新 」)。 不過,當您切換正在讀取的書寫時,輸入的作業必須遇到 EOF 標記。 如果沒有 EOF,您必須使用檔案位置的函式呼叫的中間。 檔案位置的函式是 fsetpos, fseek,和 rewind. 當您切換寫入讀取時,您必須使用其中的多餘呼叫fflush或檔案位置的函式。

除了上述的值,可以包含下列字元在mode來指定新行字元的轉譯模式:

  • t
    在文字中的開啟 (轉譯) 模式。 在此模式中,CTRL + Z 會解譯為輸入的檔案結尾字元。 在檔案開啟進行讀取/寫入與 "a+", fopen_s檢查 CTRL + Z 結尾的檔案並移除它,如果可能的話。 這是因為使用fseek和 ftell以 CTRL + Z,可能會造成檔案內移動 fseek檔案的結尾附近的不當行為。

此外,在文字模式中,換行字元 return–linefeed 組合會轉譯成輸入時,單一等等,換行字元會轉譯為在輸出上的換行字元 return–linefeed 組合。 當 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為 「 無認可 」。 這是預設值。 如果您連結您的程式與 COMMODE.OBJ,它也會覆蓋全域認可旗標。 全域認可旗標預設值是"沒有認可" 除非您明確地連結您的程式與 COMMODE。OBJ (請參閱 連結選項)。

  • N
    指定檔案並未繼承給子處理程序。

  • S
    指定的最佳化,但不是限於,循序存取從磁碟快取。

  • R
    指定的最佳化,但不是限於,隨機存取從磁碟快取。

  • T
    指定暫存檔案。 如果可能的話,沒有轉存到磁碟。

  • D
    指定暫存檔案。 當最後一個檔案指標已關閉,它會被刪除。

  • ccs=ENCODING
    指定要用於此檔案中的 (utf-8、 UTF 16LE 和 UNICODE) 的硬式編碼的字元集。 離開這未指定是否您想在 ANSI 編碼方式。

有效字元為mode字串用 fopen_s和 _fdopen對應到 oflag引數中使用 _ 開啟_sopen、,如下所示。

模式字串中的字元

對等oflag值 _open/_sopen

a

_O_WRONLY | _O_APPEND(通常是_O_WRONLY | _O_CREAT |_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

n

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 檔案也可能是一個選項。

需求

函式

所需的標頭

fopen_s

< > stdio.h

_wfopen_s

< > stdio.h 或者 < wchar.h >

其他相容性資訊,請參閱相容性在簡介中。

程式庫

所有版本的 C 執行階段程式庫

c, n,和 t  mode選項是 Microsoft 擴充功能的 fopen_s和 _fdopen,不應該使用 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 對等用法

請參閱

參考

資料流 I/O

fclose、_fcloseall

_fdopen、_wfdopen

ferror

_fileno

freopen、_wfreopen

_open、_wopen

_setmode