Delphi判斷文件是否正在被使用(CreateFile也可以只是為了讀取數據,而不是創建)


首先,我們先來認識下CreateFile函數,它的原型如下
 
HANDLE CreateFile(
 LPCTSTR  lpFileName,    //指向文件名的指針
 DWORD  dwDesiredAccess,   //訪問模式(寫/讀)
 DWORD  dwShareMode,   //共享模式
 LPSECURITY_ATTRIBUTES  lpSecurityAttributes,//指向安全屬性的指針
 DWORD  dwCreationDisposition,   //如何創建
 DWORD  dwFlagsAndAttributes,  //文件屬性
 HANDLE  hTemplateFile   //用於復制文件句柄
);
 
下面是參數的說明
 
lpFileName
   指向一個空結尾字符串。該參數指定了用於創建或打開句柄的對象。
   如果lpFileName的對象是一個路徑,則有一個最大字符數的限制。不能超過常量(MAX_PATH).這個限制指示了CreateFile函數如何解析路徑.
 
dwDesiredAccess
   指定對象的訪問方式,程序可以獲得讀訪問權,寫訪問權,讀寫訪問權或者是詢問設備("device query") 訪問權.
   這個參數可以是下列值的任意組合
     0
        指定詢問訪問權.程序可以在不直接訪問設備的情況下查詢設備的屬性.
     GENERIC_READ
        指定讀訪問權.可以從文件中讀取數據,並且移動文件指針.可以和GENERIC_WRITE組合成為"讀寫訪問權".
     GENERIC_WRITE
        指定寫訪問權.可以從文件中寫入數據,並且移動文件指針.可以和GENERIC_READ組合成為"讀寫訪問權".
 
dwShareMode
     設置位標志指明對象如何共享.如果參數是0, 對象不能夠共享. 后續的打開對象的操作將會失敗,直到該對象的句柄關閉.
     使用一個或多個下列值的組合來共享一個對象.
     FILE_SHARE_DELETE
        WINDOWS NT:后續的僅僅請求刪除訪問權的打開操作將會成功.
     FILE_SHARE_READ
        后續的僅僅請求讀訪問權的打開操作將會成功.
     FILE_SHARE_WRITE
        后續的僅僅請求寫訪問權的打開操作將會成功.
 
lpSecurityAttributes
     指向一個 SECURITY_ATTRIBUTES 結構的指針用於確定如何在子進程中繼承這個句柄.如果這個參數是NULL,則該句柄不可繼承.

dwCreationDisposition
     指定當文件存在或者不存在時如何動作。關於這個參數更多的信息,參考批注部分。這個參數必須是一個或多個下列值。
     CREATE_NEW
        創建一個新文件. 如果該文件已經存在函數則會失敗.
 
     CREATE_ALWAYS
        創建一個新文件.如果該文件已經存在,函數將覆蓋已存在的文件並清除已存在的文件屬性
     OPEN_EXISTING
        打開一個文件,如果文件不存在函數將會失敗.
        如查你使用CreateFile函數為設備裝載控制台.請查看批注中的"為什么使用OPEN_EXISTING標志"的部分.
    
     OPEN_ALWAYS
        如果文件存在,打開文件. 如果文件不存在,並且參數中有CREATE_NEW標志,則創建文件.
     TRUNCATE_EXISTING
        打開一個文件,每次打開,文件將被截至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結構)去進行文件的讀寫.這個標志也可以有超過一個操作去執行.
    FILE_FLAG_NO_BUFFERING  
        指示系統不使用快速緩沖區或緩存,當和FILE_FLAG_OVERLAPPED組合,該標志給出最大的異步操作量, 因為I/O不依賴內存管理器的異步操作.然而,一些I/O操作將會運行得長一些,因為數據沒有控制在緩存中.當使用FILE_FLAG_NO_BUFFERING打開文件進行工作時,程序必須達到下列要求:
  1.      文件的存取開頭的字節偏移量必須是扇區尺寸的整倍數.
  2.      文件存取的字節數必須是扇區尺寸的整倍數.例如,如果扇區尺寸是512字節程序就可以讀或者寫512,1024或者2048字節,但不能夠是335,981或者7171字節.
  3.      進行讀和寫操作的地址必須在扇區的對齊位置,在內存中對齊的地址是扇區尺寸的整倍數.
  4.      一個將緩沖區與扇區尺寸對齊的途徑是使用VirtualAlloc函數. 它分配與操作系統內存頁大小的整倍數對齊的內存地址.因為內存頁尺寸和扇區尺寸--2都是它們的冪.
  5.      這塊內存在地址中同樣與扇區尺寸大小的整倍數對齊.       
  6.      程序可以通過調用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.
       你也可以使用這個標志獲得一個文件夾的句柄,一個文件夾句柄能夠象一個文件句柄一樣傳給某些Win32函數。
 
    FILE_FLAG_POSIX_SEMANTICS
        指明文件符合POSIX標准.這是在MS-DOS與16位Windows下的標准.
    FILE_FLAG_OPEN_REPARSE_POINT
        指定這個標志制約NTFS分區指針.該標志不能夠和CREAT_ALWAYS一起使用.
    FILE_FLAG_OPEN_NO_RECALL
        指明需要文件數據,但是將繼續從遠程存儲器中接收.它不會將數據存放在本地存儲器中.
        這個標志由遠程存儲系統或等級存儲管理器系統使用.
 
hTemplateFile
    為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;
  
函數的調用方法: 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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM