★★★★Excel-VBA操作文件四大方法之四
2011年06月05日
四、利用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可能就能找到满意的答案。 写的这么多,希望对大家有所帮助,至少操作文件是没有什么问题了。 本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/smallboy_5/archive/2008/09/12 /2918327.aspx