首先,我們先來認識下CreateFile函數,它的原型如下
HANDLE CreateFile(
LPCTSTR lpFileName, //指向文件名的指針
DWORD dwDesiredAccess, //訪問模式(寫/讀)
DWORD dwShareMode, //共享模式
LPSECURITY_ATTRIBUTES lpSecurityAttributes,//指向安全屬性的指針
DWORD dwCreationDisposition, //如何創建
DWORD dwFlagsAndAttributes, //文件屬性
HANDLE hTemplateFile //用於復制文件句柄
);
LPCTSTR lpFileName, //指向文件名的指針
DWORD dwDesiredAccess, //訪問模式(寫/讀)
DWORD dwShareMode, //共享模式
LPSECURITY_ATTRIBUTES lpSecurityAttributes,//指向安全屬性的指針
DWORD dwCreationDisposition, //如何創建
DWORD dwFlagsAndAttributes, //文件屬性
HANDLE hTemplateFile //用於復制文件句柄
);
下面是參數的說明
lpFileName
指向一個空結尾字符串。該參數指定了用於創建或打開句柄的對象。
如果lpFileName的對象是一個路徑,則有一個最大字符數的限制。不能超過常量(MAX_PATH).這個限制指示了CreateFile函數如何解析路徑.
指向一個空結尾字符串。該參數指定了用於創建或打開句柄的對象。
如果lpFileName的對象是一個路徑,則有一個最大字符數的限制。不能超過常量(MAX_PATH).這個限制指示了CreateFile函數如何解析路徑.
dwDesiredAccess
指定對象的訪問方式,程序可以獲得讀訪問權,寫訪問權,讀寫訪問權或者是詢問設備("device query") 訪問權.
這個參數可以是下列值的任意組合
指定對象的訪問方式,程序可以獲得讀訪問權,寫訪問權,讀寫訪問權或者是詢問設備("device query") 訪問權.
這個參數可以是下列值的任意組合
0
指定詢問訪問權.程序可以在不直接訪問設備的情況下查詢設備的屬性.
指定詢問訪問權.程序可以在不直接訪問設備的情況下查詢設備的屬性.
GENERIC_READ
指定讀訪問權.可以從文件中讀取數據,並且移動文件指針.可以和GENERIC_WRITE組合成為"讀寫訪問權".
指定讀訪問權.可以從文件中讀取數據,並且移動文件指針.可以和GENERIC_WRITE組合成為"讀寫訪問權".
GENERIC_WRITE
指定寫訪問權.可以從文件中寫入數據,並且移動文件指針.可以和GENERIC_READ組合成為"讀寫訪問權".
指定寫訪問權.可以從文件中寫入數據,並且移動文件指針.可以和GENERIC_READ組合成為"讀寫訪問權".
dwShareMode
設置位標志指明對象如何共享.如果參數是0, 對象不能夠共享. 后續的打開對象的操作將會失敗,直到該對象的句柄關閉.
使用一個或多個下列值的組合來共享一個對象.
FILE_SHARE_DELETE
WINDOWS NT:后續的僅僅請求刪除訪問權的打開操作將會成功.
WINDOWS NT:后續的僅僅請求刪除訪問權的打開操作將會成功.
FILE_SHARE_READ
后續的僅僅請求讀訪問權的打開操作將會成功.
后續的僅僅請求讀訪問權的打開操作將會成功.
FILE_SHARE_WRITE
后續的僅僅請求寫訪問權的打開操作將會成功.
后續的僅僅請求寫訪問權的打開操作將會成功.
lpSecurityAttributes
指向一個 SECURITY_ATTRIBUTES 結構的指針用於確定如何在子進程中繼承這個句柄.如果這個參數是NULL,則該句柄不可繼承.
指向一個 SECURITY_ATTRIBUTES 結構的指針用於確定如何在子進程中繼承這個句柄.如果這個參數是NULL,則該句柄不可繼承.
dwCreationDisposition
指定當文件存在或者不存在時如何動作。關於這個參數更多的信息,參考批注部分。這個參數必須是一個或多個下列值。
CREATE_NEW
創建一個新文件. 如果該文件已經存在函數則會失敗.
CREATE_ALWAYS
創建一個新文件.如果該文件已經存在,函數將覆蓋已存在的文件並清除已存在的文件屬性
創建一個新文件. 如果該文件已經存在函數則會失敗.
CREATE_ALWAYS
創建一個新文件.如果該文件已經存在,函數將覆蓋已存在的文件並清除已存在的文件屬性
OPEN_EXISTING
打開一個文件,如果文件不存在函數將會失敗.
如查你使用CreateFile函數為設備裝載控制台.請查看批注中的"為什么使用OPEN_EXISTING標志"的部分.
OPEN_ALWAYS
如果文件存在,打開文件. 如果文件不存在,並且參數中有CREATE_NEW標志,則創建文件.
打開一個文件,如果文件不存在函數將會失敗.
如查你使用CreateFile函數為設備裝載控制台.請查看批注中的"為什么使用OPEN_EXISTING標志"的部分.
OPEN_ALWAYS
如果文件存在,打開文件. 如果文件不存在,並且參數中有CREATE_NEW標志,則創建文件.
TRUNCATE_EXISTING
打開一個文件,每次打開,文件將被截至0字節.調用進程必須用GENERIC_WRITE訪問模式打
開文件.如果文件不存在則函數就會失敗.
打開一個文件,每次打開,文件將被截至0字節.調用進程必須用GENERIC_WRITE訪問模式打
開文件.如果文件不存在則函數就會失敗.
dwFlagsAndatributes
為文件指定屬性和標志位
為文件指定屬性和標志位
該參數可以接收下列屬性的任意組合.除非其它所有的文件屬性忽略FILE_ATTRIBUTE_NORMAL.
FILE_ATTRIBUTE_ARCHIVE
文件將被存檔,程序使用此屬性來標志文件去備份或移除
文件將被存檔,程序使用此屬性來標志文件去備份或移除
FILE_ATTRIBUTE_HIDDEN
文件被隱藏,它不會在一般文件夾列表中被裝載.
文件被隱藏,它不會在一般文件夾列表中被裝載.
FILE_ATTRIBUTE_NORMAL
文件沒有被設置任何屬性.
文件沒有被設置任何屬性.
FILE_ATTRIBUTE_OFFLINE
文件的數據沒有被立即用到。指出正在脫機使用該文件。
FILE_ATTRIBUTE_READONLY
這個文件只可讀取.程序可以讀文件,但不可以在上面寫入內容,也不可刪除.
這個文件只可讀取.程序可以讀文件,但不可以在上面寫入內容,也不可刪除.
FILE_ATTRIBUTE_SYSTEM
文件是系統的一部分,或是系統專用的.
文件是系統的一部分,或是系統專用的.
FILE_ATTRIBUTE_TEMPORARY
文件被使用后,文件系統將努力為(文件的)所有數據的迅迅訪問保持一塊
內存。臨時文件應當在程序不用時及時刪除。
文件被使用后,文件系統將努力為(文件的)所有數據的迅迅訪問保持一塊
內存。臨時文件應當在程序不用時及時刪除。
dwFlagAndAttributes可以接受下列標志的任意組合。
FILE_FLAG_WRITE_THROUGH
指示系統通過快速緩存直接寫入磁盤.
FILE_FLAG_OVERLAPPED
指示系統初始化對象, 此操作將對進程設置一個引用計數並返回ERROR_IO_PENDING.處理完成后, 指定對象將被設置為信號狀態.當你指定FILE_FLAG_OVERLAPPED時,讀寫文件的函數必須指定一個OVERLAPPED結構.並且. 當FILE_FLAG_OVERLAPPED被指定, 程序必須執行重疊參數(指向OVERLAPPED結構)去進行文件的讀寫.這個標志也可以有超過一個操作去執行.
指示系統初始化對象, 此操作將對進程設置一個引用計數並返回ERROR_IO_PENDING.處理完成后, 指定對象將被設置為信號狀態.當你指定FILE_FLAG_OVERLAPPED時,讀寫文件的函數必須指定一個OVERLAPPED結構.並且. 當FILE_FLAG_OVERLAPPED被指定, 程序必須執行重疊參數(指向OVERLAPPED結構)去進行文件的讀寫.這個標志也可以有超過一個操作去執行.
FILE_FLAG_NO_BUFFERING
指示系統不使用快速緩沖區或緩存,當和FILE_FLAG_OVERLAPPED組合,該標志給出最大的異步操作量, 因為I/O不依賴內存管理器的異步操作.然而,一些I/O操作將會運行得長一些,因為數據沒有控制在緩存中.當使用FILE_FLAG_NO_BUFFERING打開文件進行工作時,程序必須達到下列要求:
指示系統不使用快速緩沖區或緩存,當和FILE_FLAG_OVERLAPPED組合,該標志給出最大的異步操作量, 因為I/O不依賴內存管理器的異步操作.然而,一些I/O操作將會運行得長一些,因為數據沒有控制在緩存中.當使用FILE_FLAG_NO_BUFFERING打開文件進行工作時,程序必須達到下列要求:
-
文件的存取開頭的字節偏移量必須是扇區尺寸的整倍數.
-
文件存取的字節數必須是扇區尺寸的整倍數.例如,如果扇區尺寸是512字節程序就可以讀或者寫512,1024或者2048字節,但不能夠是335,981或者7171字節.
-
進行讀和寫操作的地址必須在扇區的對齊位置,在內存中對齊的地址是扇區尺寸的整倍數.
-
一個將緩沖區與扇區尺寸對齊的途徑是使用VirtualAlloc函數. 它分配與操作系統內存頁大小的整倍數對齊的內存地址.因為內存頁尺寸和扇區尺寸--2都是它們的冪.
-
這塊內存在地址中同樣與扇區尺寸大小的整倍數對齊.
-
程序可以通過調用GetDiskFreeSpace來確定扇區的尺寸.
FILE_FLAG_RANDOM_ACCESS
指定文件是隨機訪問,這個標志可以使系統優化文件的緩沖.
指定文件是隨機訪問,這個標志可以使系統優化文件的緩沖.
FILE_FLAG_SEQUENTIAL_SCAN
指定文件將從頭到尾連續地訪問.這個標志可以提示系統優化文件緩沖. 如果程序在隨機訪問文件中移動文件指針,優化可能不會發生;然而,正確的操作仍然可以得到保證
指定這個標志可以提高程序以順序訪問模式讀取大文件的性能, 性能的提高在許多程序讀取一些大的順序文件時是異常明顯的.但是可能會有小范圍的字節遺漏.
FILE_FLAG_DELETE_ON_CLOSE
指示系統在文件所有打開的句柄關閉后立即刪除文件.不只有你可以指定FILE_FLAG_DELETE_ON_CLOSE如果沒有使用FILE_SHARE_DELETE,后續的打開文件的請求將會失敗.
FILE_FLAG_BACKUP_SEMANTICS
WINDOWS NT:指示系統為文件的打開或創建執行一個備份或恢復操作. 系統保證調用進程忽略文件的安全選項,倘若它必須有一個特權.則相關的特權則是SE_BACKUP_NAME和SE_RESTORE_NAME.
WINDOWS NT:指示系統為文件的打開或創建執行一個備份或恢復操作. 系統保證調用進程忽略文件的安全選項,倘若它必須有一個特權.則相關的特權則是SE_BACKUP_NAME和SE_RESTORE_NAME.
你也可以使用這個標志獲得一個文件夾的句柄,一個文件夾句柄能夠象一個文件句柄一樣傳給某些Win32函數。
FILE_FLAG_POSIX_SEMANTICS
指明文件符合POSIX標准.這是在MS-DOS與16位Windows下的標准.
指明文件符合POSIX標准.這是在MS-DOS與16位Windows下的標准.
FILE_FLAG_OPEN_REPARSE_POINT
指定這個標志制約NTFS分區指針.該標志不能夠和CREAT_ALWAYS一起使用.
指定這個標志制約NTFS分區指針.該標志不能夠和CREAT_ALWAYS一起使用.
FILE_FLAG_OPEN_NO_RECALL
指明需要文件數據,但是將繼續從遠程存儲器中接收.它不會將數據存放在本地存儲器中.
這個標志由遠程存儲系統或等級存儲管理器系統使用.
指明需要文件數據,但是將繼續從遠程存儲器中接收.它不會將數據存放在本地存儲器中.
這個標志由遠程存儲系統或等級存儲管理器系統使用.
hTemplateFile
為GENERIC_READ訪問的模式指定一個句柄到模板文件.模板文件在文件開始創建后提供文件屬性和擴展屬性.
為GENERIC_READ訪問的模式指定一個句柄到模板文件.模板文件在文件開始創建后提供文件屬性和擴展屬性.
Return Values
返回值
返回值
如果函數成功,返回一個打開的指定文件的句柄.如果指定文件在函數調用前已經存在並且dwCreation參數是CREATE_ALWAYS 或者OPEN_ALWAYS,調用GetLastError就會返回ERROR_ALREADY_EXISTS(表示函數成功). 如果函數文件在調用前不存在則會返回0.
如果函數失敗,返會值會是INVALID_HANDLE_VALUE. 更多的錯誤信息可以調用GetLastError來獲得.
好了 上面唧唧歪歪這么多 主要就是要大家在看下面的這個 “判斷文件是否正在被使用”的函數更容易理解一些,函數如下:
function IsFileInUse(fName :string) : boolean;
var
HFileRes : HFILE;
begin
Result := false; //返回值為假(即文件不被使用)
if not FileExists(fName) then exit; //如果文件不存在則退出
HFileRes := CreateFile(pchar(fName), GENERIC_READ or GENERIC_WRITE,
0 {this is the trick!}, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
Result := (HFileRes = INVALID_HANDLE_VALUE); //如果CreateFile返回失敗 那么Result為真(即文件正在被使用)
if not Resultthen //如果CreateFile函數返回是成功
CloseHandle(HFileRes); //那么關閉句柄
end;
var
HFileRes : HFILE;
begin
Result := false; //返回值為假(即文件不被使用)
if not FileExists(fName) then exit; //如果文件不存在則退出
HFileRes := CreateFile(pchar(fName), GENERIC_READ or GENERIC_WRITE,
0 {this is the trick!}, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
Result := (HFileRes = INVALID_HANDLE_VALUE); //如果CreateFile返回失敗 那么Result為真(即文件正在被使用)
if not Resultthen //如果CreateFile函數返回是成功
CloseHandle(HFileRes); //那么關閉句柄
end;
函數的調用方法:
IsFileInUse(要判斷的文件路徑); 如果函數返回True 則正在使用,False則文件現在沒被使用
參考:http://blog.csdn.net/sforiz/article/details/6918719
------------------------------------------------------------------------------
再來一篇:windows api 每日一練(3)文件操作
#include <windows.h> #include <stdio.h> #include <iostream> int main() { std::wstring originalStrFile(L"./test.txt"); HANDLE hFile; hFile = CreateFile(originalStrFile.c_str(), // file to open GENERIC_READ, // open for reading FILE_SHARE_READ, // share for reading NULL, // default security OPEN_EXISTING, // existing file only FILE_ATTRIBUTE_NORMAL, // normal file NULL); //獲取文件大小 DWORD dwSize =GetFileSize(hFile,NULL); //獲取文件類型 DWORD fileType=GetFileType(hFile); //獲取文件時間信息 FILETIME time1; FILETIME time2; FILETIME time3; GetFileTime(hFile,&time1,&time2,&time3); //獲取文件名 DWORD bufferLength=100; TCHAR buffer[100]=TEXT(""); TCHAR* lpPart[100]={NULL}; //獲取全名 GetFullPathName(originalStrFile.c_str(),bufferLength,buffer,lpPart); //獲取長路徑名 GetLongPathName(originalStrFile.c_str(),buffer,bufferLength); //獲取短路徑名 GetShortPathName(originalStrFile.c_str(),buffer,bufferLength); //關閉句柄對象 CloseHandle(hFile); }
參考:http://www.cnblogs.com/Clingingboy/archive/2009/11/17/1604391.html