★★★★Excel-VBA操作文件四大方法之四

 

四、利用API函數來處理文件

通過前面三種方法的介紹,你是否已經覺得足夠了?是的,前面的方法完全可以應付幾乎所有的文件操作。但是爲了普及一下API,展示一下API的魅力,最後向大家介紹一下如何利用API函數來處理文件。另一方面也是本人對API情有獨鍾,爲她做一下廣告,呵呵。

大家對API的強大也是有所耳聞了,在文件操作方面,API自然毫不遜色。
說明:爲了文章簡潔,我們先給出API函數的名稱及功能,其完整的聲明及常數就不再一一細訴,只在示例中給出其完整用法。

(二)處理文件

下面是windows中提供的對於文件進行操作的API函數及其功能:

CloseHandle   關閉一個內核對象。其中包括文件、文件映射、進程、線程、安全和同步對象等。
CompareFileTime  根據FILETIME結構的信息,對比兩個文件的時間
CopyFile   複製文件。注意:只能複製文件,而不能複製目錄
CreateFile   這是一個全功能的函數,可打開和創建文件、管道、郵槽、通信服務、設備以及控制檯
DeleteFile   刪除指定文件
FindClose   關閉由FindFirstFile函數創建的一個搜索句柄
FindFirstFile   根據文件名查找文件
FindNextFile   根據調用FindFirstFile函數時指定的一個文件名查找下一個文件
FlushFileBuffers  針對指定的文件句柄,刷新內部文件緩衝區
GetBinaryType   判斷文件是否可以執行
GetFileAttributes  判斷指定文件的屬性
GetFileInformationByHandle 該函數能夠獲取上面所有函數所能夠獲取的信息,如大小、屬性等,同時還包括一些其他地方無法獲取的信息,比如:文件卷標、索引和鏈接信息。
GetFileSize   判斷文件長度
GetFileTime   取得指定文件的時間信息,有三個文件時間:創建時間、最後訪問時間、最後寫時間。
GetFileType   在給出文件句柄的前提下,判斷文件類型
GetFileVersionInfo  從支持版本標記的一個模塊裏獲取文件版本信息
GetFileVersionInfoSize  針對包含了版本資源的一個文件,判斷容納文件版本信息需要一個多大的緩衝區
GetFullPathName  獲取文件路徑,該函數獲取文件的完整路徑名。注意:只有當該文件在當前目錄下,
   結果才正確。如果要得到真正的路徑。應該用GetModuleFileName函數。
GetShortPathName  獲取指定文件的短路徑名
GetTempFileName  這個函數包含了一個臨時文件的名字,它可由應用程序使用
GetTempPath   獲取Windows臨時目錄路徑
lclose    關閉指定的文件,請參考CloseHandle函數,瞭解進一步的情況
lcreat    創建一個文件。如文件已經存在,就會將其縮短成零長度,並將其打開,以便讀寫
llseek    設置文件中進行讀寫的當前位置。該函數與vba的seek語句類似。
LockFile   在windows中,文件可用共享模式打開——在這種情況下,多個進程可同時訪問該文件。
   利用這個函數,要對文件進行讀寫的一個應用程序可將文件的某一部分鎖定起來,使其
   不能由其他應用程序訪問。這樣便避免了同時讀寫時發生的衝突
LockFileEx   與LockFile相似,只是它提供了更多的功能
lopen    以二進制模式打開指定的文件
lread    將文件中的數據讀入內存緩衝區
lwrite    將數據從內存緩衝區寫入一個文件
MoveFile, MoveFileEx  移動文件。如dwFlags設爲零,則MoveFile完全等價於MoveFileEx
OpenFile   這個函數能執行大量不同的文件操作。和這個函數相比,請優先考慮CreateFile函數
   (它能打開命名管道和控制Unicode文件名,同時不受128個字符的路徑名稱的限制)
ReadFile   從文件中讀出數據。與lread函數相比,這個函數要明顯靈活的多。該函數能夠操作
   通信設備、管道、套接字以及郵槽
ReadFileEx   與ReadFile相似,只是它只能用於異步讀操作,幷包含了一個完整的回調
SearchPath   查找指定文件
SetEndOfFile   針對一個打開的文件,將當前文件位置設爲文件末尾
SetFileAttributes  設置文件屬性
SetFilePointer   在一個文件中設置當前的讀寫位置
SetFileTime   設置文件的創建、訪問及上次修改時間
UnlockFile   解除對一個文件的鎖定
UnlockFileEx   解除對一個文件的鎖定
WriteFile   將數據寫入一個文件。該函數比lwrite函數要靈活的多。也可將這個函數應用於對
   通信設備、管道、套接字以及郵槽的處理
WriteFileEx   與WriteFile類似,只是它只能用於異步寫操作,幷包括了一個完整的回調


文件的壓縮和解壓縮

LZOpenFile   打開壓縮文件以讀取
LZSeek    查找壓縮文件中的一個位置
LZRead    讀一個壓縮文件
LZClose   關閉一個壓縮文件
LZCopy    複製壓縮文件並在處理過程中展開
GetExpandedName  從壓縮文件中返回文件名稱。


下面通過幾個例子來詳細的瞭解一下其中主要的幾個函數及其用法:

1、CreateFile

作用:這是一個全功能的例程,可打開和創建文件、管道、郵槽、通信服務、設備以及控制檯

聲明:
Declare Function CreateFile Lib "kernel32" Alias "CreateFileA" (ByVal lpFileName As String, ByVal dwDesiredAccess As Long, ByVal dwShareMode As Long, lpSecurityAttributes As SECURITY_ATTRIBUTES, ByVal dwCreationDisposition As Long, ByVal dwFlagsAndAttributes As Long, ByVal hTemplateFile As Long) As Long

說明:
此函數的返回值類型爲Long,如執行成功,則返回文件句柄。INVALID_HANDLE_VALUE表示出錯,會設置GetLastError。即使函數成功,但若文件存在,且指定了CREATE_ALWAYS 或 OPEN_ALWAYS,GetLastError也會設爲ERROR_ALREADY_EXISTS

打開一個通信端口時(如COM1),無論如何都要設置成 OPEN_EXISTING。

這個函數代替了lOpen 和 lCreate函數,應該是我們的首選

參數說明:

·lpFileName   String,要打開的文件的名字
·dwDesiredAccess  Long,如果爲 GENERIC_READ 表示允許對設備進行讀訪問;如果爲 GENERIC_WRITE 表示允許對設備進行寫訪問(可組合使用);如果爲零,表示只允許獲取與一個設備有關的信息
·dwShareMode   Long,零表示不共享; FILE_SHARE_READ 和/或 FILE_SHARE_WRITE 表示允許對文件進行共享訪問
·lpSecurityAttributes  SECURITY_ATTRIBUTES,指向一個SECURITY_ATTRIBUTES結構的指針,定義了文件的安全特性(如果操作系統支持的話)
 
·dwCreationDisposition
Long,下述常數之一:
CREATE_NEW   創建文件;如文件存在則會出錯
CREATE_ALWAYS   創建文件,會改寫前一個文件
OPEN_EXISTING   文件必須已經存在。由設備提出要求
OPEN_ALWAYS   如文件不存在則創建它
TRUNCATE_EXISTING  講現有文件縮短爲零長度

·dwFlagsAndAttributes
Long,一個或多個下述常數
FILE_ATTRIBUTE_ARCHIVE   標記歸檔屬性
FILE_ATTRIBUTE_COMPRESSED  將文件標記爲已壓縮,或者標記爲文件在目錄中的默認壓縮方式
FILE_ATTRIBUTE_NORMAL   默認屬性
FILE_ATTRIBUTE_HIDDEN   隱藏文件或目錄
FILE_ATTRIBUTE_READONLY  文件爲只讀
FILE_ATTRIBUTE_SYSTEM   文件爲系統文件
FILE_FLAG_WRITE_THROUGH  操作系統不得推遲對文件的寫操作
FILE_FLAG_OVERLAPPED   允許對文件進行重疊操作
FILE_FLAG_NO_BUFFERING   禁止對文件進行緩衝處理。文件只能寫入磁盤卷的扇區塊
FILE_FLAG_RANDOM_ACCESS  針對隨機訪問對文件緩衝進行優化
FILE_FLAG_SEQUENTIAL_SCAN  針對連續訪問對文件緩衝進行優化
FILE_FLAG_DELETE_ON_CLOSE  關閉了上一次打開的句柄後,將文件刪除。特別適合臨時文件
也可在Windows NT下組合使用下述常數標記:
SECURITY_ANONYMOUS, SECURITY_IDENTIFICATION, SECURITY_IMPERSONATION, SECURITY_DELEGATION, SECURITY_CONTEXT_TRACKING, SECURITY_EFFECTIVE_ONLY
 
·hTemplateFile  Long,如果不爲零,則指定一個文件句柄。新文件將從這個文件中複製擴展屬性

示例如下:

lngHandle = CreateFile("c:/text.txt", GENERIC_WRITE, FILE_SHARE_READ Or FILE_SHARE_WRITE, ByVal 0&, OPEN_ALWAYS, 0, 0)

'上面代碼以寫方法打開文件,如文件不存在則創建它。

2、lcreat

作用:創建一個文件。如文件已經存在,就會將其縮短成零長度,並將其打開,以便讀寫

聲明:Declare Function lcreat Lib "kernel32" Alias "_lcreat" (ByVal lpPathName As String, ByVal iAttribute As Long) As Long

說明:此函數的返回值類型爲Long,如執行成功,返回打開文件的句柄。如果出錯,則返回HFILE_ERROR

該函數會打開已由其他應用程序打開的文件,所以使用它時要小心。win32的CreateFile函數已取代了這個函數。這個函數與vb的open語句作用相同

參數說明:

lpPathName String,欲創建的文件的名字
iAttribute Long,下述值之一:

0——文件能夠讀寫
1——創建只讀文件
2——創建隱藏文件
3——創建系統文件
 
示例:
下面的語句打開c:/test.txt文件

lcreat “c:/test.txt”,0

3、lopen

作用:以二進制模式打開指定的文件

聲明:Declare Function lopen Lib "kernel32" Alias "_lopen" (ByVal lpPathName As String, ByVal iReadWrite As Long) As Long

說明:此函數的返回值類型爲Long,如執行成功,返回打開文件的句柄。HFILE_ERROR表示出錯。會設置GetLastError

參數說明:

lpPathName String,欲打開文件的名字
iReadWrite Long,訪問模式和共享模式常數的一個組合,如下所示:
1、訪問模式
READ   打開文件,讀取其中的內容
READ_WRITE  打開文件,對其進行讀寫
WRITE   打開文件,在其中寫入內容
2、共享模式(參考OpenFile函數的標誌常數表)
OF_SHARE_COMPAT, OF_SHARE_DENY_NONE, OF_SHARE_DENY_READ, OF_SHARE_DENY_WRITE, OF_SHARE_EXCLUSIVE

示例:
lopen “c:/test.txt”,READ

4、GetFileTime

作用:取得指定文件的時間信息

聲明:Declare Function GetFileTime Lib "kernel32" Alias "GetFileTime" (ByVal hFile As Long, lpCreationTime As FILETIME, lpLastAccessTime As FILETIME, lpLastWriteTime As FILETIME) As Long

說明:Long,非零表示成功,零表示失敗。會設置GetLastError

如果不需要特定的信息,那麼lpCreationTime,lpLastAccessTime,lpLastWriteTime都可以設置爲零(用ByVal As Long)。這個函數返回的文件時間採用UTC格式

參數說明:
hFile Long,文件的句柄
lpCreationTime   FILETIME,用於裝載文件的創建時間
lpLastAccessTime  FILETIME,用於裝載文件上一次訪問的時間(FAT文件系統不支持這一特性)
lpLastWriteTime  FILETIME,用於裝載文件上一次修改的時間

示例:

Dim file As Long
Dim CreationTime As FileTime
Dim lastaccesstime As FileTime
Dim lastaccesstime As FileTime
'定義結構
Private Type FileTime
 dwLowDateTime As Long
 dwHighDateTime As Long
End Type

 str1 = "c:/text.txt"
 file = lopen(str1, READ_WRITE) ‘打開文件
 temp = GetFileTime(file, CreationTime, lastaccesstime, lastwritetime)’得到文件相關信息

以上代碼獲取的時間信息是Long型的,還需要時間轉換函數進行轉換,完整的示例見附件。

5、CopyFile

作用:複製文件。與vb的filecopy命令相似

聲明:Declare Function CopyFile Lib "kernel32" Alias "CopyFileA" (ByVal lpExistingFileName As String, ByVal lpNewFileName As String, ByVal bFailIfExists As Long) As Long

說明:Long,非零表示成功,零表示失敗。會設置GetLastError

參數說明:

lpExistingFileName  String,源文件名
lpNewFileName   String,目標文件名
bFailIfExists   Long,如果設爲TRUE(非零),那麼一旦目標文件已經存在,則函數調用會失敗。否則目標文件被改寫


示例:
CopyFile "c:/test1.txt", "c:/test2.txt", 1

以上代碼將c:/test1.txt 拷貝到c:/test2.txt,完整的示例見附件。

6、MoveFile, MoveFileEx

作用:移動文件。如dwFlags設爲零,則MoveFile完全等價於MoveFileEx

聲明:
Declare Function MoveFile Lib "kernel32" Alias "MoveFileA" (ByVal lpExistingFileName As String, ByVal lpNewFileName As String)

Declare Function MoveFileEx Lib "kernel32" Alias "MoveFileExA" (ByVal lpExistingFileName As String, ByVal lpNewFileName As String, ByVal dwFlags As Long)

說明:Long,非零表示成功,零表示失敗。會設置GetLastError

這兩個函數通常不能將文件從一個卷移動到另一個卷。但如設置了MOVEFILE_COPY_ALLOWED標記,MoveFileEx可以做到這一點.

參數說明:

lpExistingFileName  String,欲移動的文件名
lpNewFileName   String,新文件名
dwFlags   Long,一個或多個下述常數
MOVEFILE_REPLACE_EXISTING 如目標文件存在,則將其替換
MOVEFILE_COPY_ALLOWED  如移動到一個不同的卷,則複製文件並刪除原來的文件
MOVEFILE_DELAY_UNTIL_REBOOT 移動操作在系統下次重新啓動時正式進行。這樣便可在Windows NT中改換系統文件

示例:
Private Const MOVEFILE_COPY_ALLOWED = &H2
Private Const MOVEFILE_DELAY_UNTIL_REBOOT = &H4
Private Const MOVEFILE_REPLACE_EXISTING = &H1

 MoveFile "c:/test.txt", "d:/test1.txt" ‘移動文件
 MoveFileEx "d:/test1.txt", "c:/test.txt", MOVEFILE_COPY_ALLOWED ‘再一次移動

以上代碼實現了文件的移動,兩次移動後,文件不變

7、DeleteFile

作用:刪除指定文件

聲明:Declare Function DeleteFile Lib "kernel32" Alias "DeleteFileA" (ByVal lpFileName As String) As Long

說明:Long,非零表示成功,零表示失敗。會設置GetLastError

與vba的kill語句相似,在windows 95下使用這個函數要小心——即使文件當前正由一個應用程序打開,該函數也會將其刪除.

參數說明:
lpFileName String,欲刪除文件的名字

示例:

DeleteFile "c:/test.txt"  '刪除c:/test.txt文件

完整的示例見附件。

8、ReadFile

作用:從文件中讀出數據。與lread函數相比,這個函數要明顯靈活的多。該函數能夠操作通信設備、管道、套接字以及郵槽

聲明:Private Declare Function ReadFile Lib "kernel32" Alias "ReadFile" (ByVal hFile As Long, lpBuffer As Any, ByVal nNumberOfBytesToRead As Long, lpNumberOfBytesRead As Long, lpOverlapped As OVERLAPPED) As Long

說明:Long,非零表示成功,零表示失敗。會設置GetLastError。如啓動的是一次異步讀操作,則函數會返回零值,並將ERROR_IO_PENDING設置成GetLastError的結果。如結果不是零值,但讀入的字節數小於nNumberOfBytesToRead參數指定的值,表明早已抵達了文件的結尾

參數:
hFile ---- Long,文件的句柄
lpBuffer ---  Any,用於保存讀入數據的一個緩衝區
nNumberOfBytesToRead -  Long,要讀入的字符數
lpNumberOfBytesRead -  Long,從文件中實際讀入的字符數
lpOverlapped ---  OVERLAPPED,如文件打開時指定了FILE_FLAG_OVERLAPPED,那麼必須用這個參數引用一個特殊的結構。那個結構定義了一次異步讀取操作。否則,應將這個參數設爲NULL(將函數聲明成ByVal As Long,並傳遞零值)

示例:完整的示例見附件。

9、WriteFile

作用:將數據寫入一個文件。該函數比lwrite函數要靈活的多。也可將這個函數應用於對通信設備、管道、套接字以及郵槽的處理

聲明:Declare Function WriteFile Lib "kernel32" Alias "WriteFile" (ByVal hFile As Long, lpBuffer As Any, ByVal nNumberOfBytesToWrite As Long, lpNumberOfBytesWritten As Long, lpOverlapped As OVERLAPPED) As Long

說明:Long,TRUE(非零)表示成功,否則返回零。會設置GetLastError

參數:
hFile ---  Long,一個文件的句柄
lpBuffer --- Any,要寫入的一個數據緩衝區
nNumberOfBytesToWrite -  Long,要寫入數據的字節數量。如寫入零字節,表示什麼都不寫入,但會更新文件的“上一次修改時間”。針對位於遠程系統的命名管道,限制在65535個字節以內

lpNumberOfBytesWritten -  Long,實際寫入文件的字節數量

lpOverlapped ---  OVERLAPPED,倘若在指定FILE_FLAG_OVERLAPPED的前提下打開文件,這個參數就必須引用一個特殊的結構。那個結構定義了一次異步寫操作。否則,該參數應置爲空(將聲明變爲ByVal As Long,並傳遞零值)

示例:完整的示例見附件。


10、SHFileOperation

作用:此函數的功能很強大,能對文件或文件夾進行復制、移動、重命名、刪除的全部操作。

聲明:Declare Function SHFileOperation Lib "shell32.dll" Alias "SHFileOperationA" (lpFileOp As SHFILEOPSTRUCT) As Long

說明:Long,TRUE(非零)表示成功,否則返回零。

參數:
lpFileOp --SHFILEOPSTRUCT類型,指定文件的操作。
Type SHFILEOPSTRUCT
        hwnd As Long
        wFunc As Long       '對文件的操作指令
        pFrom As String     '源文件或路徑
        pTo As String       '目的文件或路徑
        fFlags As Integer   '操作標誌
        fAnyOperationsAborted As Long
        hNameMappings As Long
        lpszProgressTitle As String
End Type

示例:見附件。


(三)總結

通過以上的介紹,我們可以看到API在文件操作方面功能十分強大,能夠完成一些前面方法所不能完成的任務。FileSystemObject對象模型的內部可能就是用API寫的,即便不是我們也可以用API寫出一個FSO類來。API是一個巨大的寶庫,當你爲實現某個功能而愁眉不展的時候,查查API可能就能找到滿意的答案。

寫的這麼多,希望對大家有所幫助,至少操作文件是沒有什麼問題了。

發佈了46 篇原創文章 · 獲贊 16 · 訪問量 31萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章