標籤:span vs2015 https sea 參數 uri 限制 ifd files
- 001_函數的不同版本
- HANDLE : CreateFile()函數返回一個核心對象的控制代碼
- WINAPI : 一種呼叫慣例,調用方式。
- _In_ 與 _In_opt_ : 本身沒有意義,一個說明宏,來標明這個參數的性質。
- _In_ 說明此參數是“輸入型”參數
- _In_Opt_ 說明此參數是“輸入指標型”參數
- _Out_ 說明此參數是“輸出型”參數
- VS2015中,CreateFile()是一個宏:
WINBASEAPI HANDLE WINAPI CreateFileA(
_In_ LPCSTR lpFileName,
……
);
?
WINBASEAPI HANDLE WINAPI CreateFileW(
_In_ LPCWSTR lpFileName,
……
);
?
#ifdef UNICODE
#define CreateFile CreateFileW
#else
#define CreateFile CreateFileA
#endif // !UNICODE
- windows平台編程,關於字元的處理,需要區分兩大陣營:1 寬字元集 與 2 窄字元集
- “寬”與“窄”兩種不同的位元組集,會導致類型的不同; 最初CreateFile函數支援的是窄位元組,後來發現窄位元組在多國語言環境中,是不夠用的,windows的設計者們,把CreateFile函數變成一個宏,這個宏使得CreateFile有了CreateFileA()與 CreateFileW()兩個版本。CreateFileA()相容窄位元組,CreateFileW()推廣寬位元組。
- 實際使用過程中,造成了很多的不方便 :
- 樣本1:
wchar_t *filename = L"d:\\1.txt";
CreateFile(filename,……);
- 看範例程式碼,此時程式員以寬位元組設定 filename,但是當外部變換為“窄”位元組集時,CreateFile這個宏,能變換成CreateFileW這個版本,而wchar_t * filename不能自動相容“窄”位元組。所以就出現了“TCHAR”這個宏,而右邊也出現了“TEXT()”這個宏。
- TEXT()這個宏,作用是:當環境為UNICODE時,在字串前面加“L”;否則不加“L”。
- 以上整套處理方案,不能移植到linux上,需要完全的重寫。
- 002_CreateFile參數詳解
- 參見下面中文翻譯
- 事務型操作:
- 把一個操作分成“讀”“寫”“修改”“完成”4個部分,中間123任意部分失敗,則操作無效,“復原”到操作進行之前的狀態。
- 比如程式安裝,可以做成一個“事務型”操作,只有當整體完成,這個事務型操作,才算真正的完成,否則“復原”至安裝之前的狀態。
- 只有在同步時,會考慮事務型操作;當非同步時,事務型操作是不適用的。
- lpFileName 檔案名稱
- ANSI版本中MAX_PATH 宏 代替 260;Unicode版本中,沒有限制長度。
- dwDesiredAccess 許可權:以何種許可權開啟檔案
- 可以多個許可權疊加使用
- 如置為0,則裝置不具有讀和寫的許可權。比如我們只要訪問一檔案的建立時間,不需要對檔案讀和寫時,這個設定就非常的合適。
- dwShareMode 共用模式
- 一系列共用給別人的模式。
- 如置為0,別的程式佔用了這個檔案,那麼無法再次被開啟。
- 當訪問模式衝突時,有GetLastError返回ERROR_SHARING_VIOLATION
- 核心對象開啟之後,需要關閉。否則此項設定的許可權一直生效。
- lpSecurityAttributes 安全性描述元
- dwCreationDisposition 當檔案存在與否時,針對存在與否,展開何種操作
- CREATE_ALWAYS 問題建立一個新檔案
- 檔案被重寫成功時,將last-error code設定為ERROR_ALREADY_EXISTS
- 檔案不存在,建立成功時,將last-error code 設定為0。
- CREATE_NEW 僅檔案不存在時,才建立一個新檔案
- 如檔案存在,執行失敗,將last-error code設定為ERROR_FILE_EXISTS
- OPEN_ALWAYS 總是開啟一個檔案
- 檔案存在,執行成功,置為ERROR_ALREADY_EXISTS
- 檔案不存在,路徑名合法且可寫時,建立一個新檔案,last-error code置為0 。
- OPEN_EXISTING 僅在檔案存在時,開啟它
- 檔案不存在,則置為ERROR_FILE_NOT_FOUND
- TRUNCATE_EXISTING 測試一個檔案是否存在
- 僅當檔案存在時,才開啟一個檔案並且,將其大小截取到0位元組
- 檔案不存在,函數執行失敗,last-error code置為ERROR_FILE_NOT_FOUND
- dwFlagsAndAttributes
- 003_CreateFile完成
- dwFlagsAndAttributes 屬性與標記位
- 對於檔案 FILE_ATTRIBUTE_NORMAL是最常用 預設值
- 設定檔案的屬性值的組合,所有屬性值是: FILE_ATTRIBUTE_NORMAL
- FILE_FLAG_BACKUP_SEMANTICS
- FILE_FLAG_NO_BUFFERING
- FILE_FLAG_WRITE_THROUGH
- hTemplateFile 核心相同的對象
- 一般為NULL
- 當不為NULL時,上一參數dwFlagsAndAttributes所有設定無效,將繼承此參數,也就是新給出的核心對象,繼承此對象的所有Flags.
- 傳回值
- 返迴文件控制代碼
- 如果失敗,返回last-error code 為 INVALID_HANDLE_VALUE
- 備忘 具體查看MSDN 曆史問題,疑難問題,在出問題時查看
- CreateFile中文翻譯:
- 函數功能
- CreateFile 函數用於建立或開啟一個檔案或者 I/O 裝置。最常使用的 I/O 裝置如下:
- 檔案
- 檔案流
- 檔案夾
- 物理磁碟
- 邏輯磁碟機
- 控制台程式緩衝區
- 磁帶
- 通訊資源
- 郵槽
- 管道
- 此函數返回一個指向用於訪問來自不同類型I/O的檔案或裝置的控制代碼,其存取權限取決於它所訪問的檔案、裝置和我們所指定的標記位、屬性。
- 為了使之可以處理事務型 I/O,請使用 CreateFileTransacted 函數。
- 函數原型
- 參數解析
- lpFileName
- 1 指定要開啟、建立的檔案或裝置的名字。你可以在名字中使用斜杠(/)或者反斜線(\)
- 2 在此函數的 ANSI 版本中,名字長度被限制為 MAX_PATH 個字元。為了將此限制擴充到 32767 個寬字元,需要調用此函數的 Unicode 版本,並且在添加在路徑名中添加 “\?\” 首碼。擷取更多的資訊,參見 Naming Files, Paths, and Namespaces
- 3 想擷取關於特殊裝置的名字,參見 Defining an MS-DOS Device Name
- 4 為了建立一個檔案流,需要指定檔案名稱,一個冒號加上流檔案的名字。擷取更多資訊,參見 File Streams
- dwDesiredAccess
- 指定以何種許可權開啟檔案或裝置,可以歸納為:讀訪問權、寫訪問權、讀寫訪問權、非讀非寫訪問權
- 最常使用的值為 GENERIC_READ, GENERIC_WRITE, 或者二者都用(GENERIC_READ | GENERIC_WRITE)。擷取更多資訊,參見 Generic Access Rights, File Security and Access Rights, File Access Rights Constants 和 ACCESS_MASK
- 如果參數值為 0,那麼程式可以在不訪問檔案或裝置情況下,詢問某些中繼資料,如檔案、目錄或者裝置屬性。此外,即使 GENERIC_READ 請求,也會被拒絕
- 你無法請求一個與共用模式衝突的存取權限。共用模式是在參數 dwShareMode 中設定的
- 擷取更多資訊,參見本文備忘以及 Creating and Opening Files
- dwShareMode
- 設定檔案或者裝置的共用模式,包括讀、寫、讀寫、刪除、全部許可權或者以上什麼許可權都沒有(參考下面的表格)。此參數不影響對屬性和擴充屬性的訪問請求
- 如果此參數為 0 且 CreateFile 函數執行成功,那麼此檔案或裝置無法被共用,且在其控制代碼被關閉前,無法被再次開啟。更多資訊,參見本文備忘。
- 你無法設定一個與訪問模式相衝突的共用模式。此時如果 CreateFile 函數執行失敗,那麼 GetLastError 函數會返回 ERROR_SHARING_VIOLATION
- 為了允許進程去共用一個已經在另一個進程中開啟的檔案或控制代碼,那麼可對以下一個或多個取值進行組合,且各取值間需要可互相相容。更多有關此參數與 dwDesiredAccess 參數的合法取值組合的資訊,參見 Creating and Opening Files
- 注意:在控制代碼被關閉之前,每個控制代碼的共用選項都會一直生效,且與進程的運行上下文(process context)無關。
- lpSecurityAttributes
- 指向 SECURITY_ATTRIBUTES 結構體的指標。此結構體擁有兩個分開但是相關的資料成員:一個是可選的安全性描述元,另一個是決定返回的控制代碼是否可以被子進程繼承的 Boolean 值
- 此參數可以設定為 NULL
- 如果參數為 NULL,那麼 CreateFile 函數返回的控制代碼無法被任意此進程的子進程所繼承,且與返回的控制代碼所對應的檔案或控制代碼擁有一個預設的安全性描述元
- 該結構體的 lpSecurityDescriptor 成員為檔案或裝置指定一個安全性描述元(SECURITY_DESCRIPTOR)。如果此成員取值為 NULL,那麼與返回的控制代碼所對應的檔案或控制代碼擁有一個預設的安全性描述元
- 當開啟一個已經存在的檔案或裝置時,CreateFile 函數忽略 lpSecurityDescriptor 成員,但是 bInheritHandle 成員仍然可以使用
- 結構體的 bInheritHandle 成員用於設定返回的控制代碼是否可以被繼承
- 更多資訊,參見本文備忘
- dwCreationDisposition
- 用於設定當檔案存在或不存在時,要對檔案或裝置執行何種操作
- 對於裝置來說,此參數通常設定為 OPEN_EXISTING
- 更多資訊,參見本文備忘
- 這個參數的值必須為以下值之一,且只能選擇一個而不能組合多個:
- dwFlagsAndAttributes
- 檔案或裝置的屬性值和標記位,對於檔案來說,FILE_ATTRIBUTE_NORMAL 是最常用的預設值
- 此參數可以是任意檔案屬性值(FILE_ATTRIBUTE_*)的組合。所有其他的檔案屬性值會覆蓋 FILE_ATTRIBUTE_NORMAL
- 此參數也可以包含任意標記位(FILE_FLAG_*)的組合以控制檔案或裝置的行為、使用權限設定和其他目的。此外,還可以與任意 FILE_ATTRIBUTE_* 進行組合
- 這個參數還可以通過指定 SECURITY_SQOS_PRESENT 標記來包含 Security Quality of Service (SQOS) 資訊。與SQOS相關的標記位資訊見屬性與標記位表格下面的表格中
- 注意:當CreateFile 開啟一個已存在的檔案時,它通常將檔案屬性和檔案標記位組合在一起,並且忽略在 dwFlagsAndAttributes 中定義的屬性值。詳細例子見 Creating and Opening Files
- 以下的屬性和標記位可能只適用於檔案的開啟,而並非支援所有其他 CreateFile 函數可以開啟的裝置。想瞭解更多資訊,參見本文備忘部分和 Creating and Opening Files。想進一步瞭解檔案屬性相關資訊,參見 SetFileAttributes 函數。你還可以在 File Attribute Constants 中看到完整的介紹所有檔案屬性的值和對應描述資訊
- hTemplateFile
- 指向一個擁有 GENERIC_READ 存取權限的的模板檔案的合法控制代碼
- 此模板檔案為即將建立的檔案提供屬性和擴充屬性
- 參數值可以為 NULL
- 如果開啟一個已存在的檔案,則 CreateFile 函數忽略這個參數
- 如果開啟一個新的被加密檔案,此函數從其父目錄中繼承自由存取控制列表。更多資訊,見 File Encryption
PoEdu - Windows階段班 【Po學校】Windows編程 Lesson004_003-2 檔案操作