Windows 编程/文件管理
本章将讨论文件和目录管理的一些细节。一些讨论的主题包括移动和删除文件和目录、枚举文件、锁定文件、加密文件以及访问回收站。
文件属性可用于写入保护、隐藏和取消隐藏文件,或作为后台文件维护。可以使用 **GetFileAttributes** 函数访问此信息。这些属性称为只读、隐藏、存档和系统,下面将对其进行描述
**只读**:标记为只读的文件无法更改。它可以被读取,但不能被更改或删除。
**隐藏**:默认情况下,隐藏文件不会出现在目录列表中。
**存档**:存档属性可用于选择性地备份或复制文件;它在 DOS 中最有用。
**系统**:系统文件是为操作系统使用而标记的文件,通常不会显示在目录列表中。
要复制文件或目录,可以使用两个函数:**CopyFile** 和扩展的 **CopyFileEx**。
BOOL CopyFile( LPCTSTR lpExistingFileName, // ptr to the name of the file/directory to copy LPCTSTR lpNewFileName, // ptr to filename to copy to BOOL bFailIfExists // flag for operation if file exists );
**lpExistingFileName**:指向包含要复制的文件/目录的字符串的指针
**lpNewFileName**:指向包含新文件/目录路径的字符串的指针
**bFailIfExists**:如果此参数为 TRUE 且新文件已存在,则函数将失败;如果为 FALSE,则将覆盖现有文件/目录。
如果函数失败,则返回值为零,否则为非零。
**CopyFileEx** 稍微复杂一些。您还可以指定在复制文件的一部分时调用的回调例程。您也可以取消复制操作,如果您想稍后重新启动它。
BOOL CopyFileEx( LPCWSTR lpExistingFileName, // pointer to name of an existing file LPCWSTR lpNewFileName, //pointer to filename to copy to LPPROGRESS_ROUTINE lpProgressRoutine, // pointer to the callback function LPVOID lpData, //data to be passed to the callback function LPBOOL pbCancel, //flag that can be used to cancel the operation DWORD dwCopyFlags //flags that specify how the file is copied );
**lpProgressRoutine**:您可以设置一个回调函数,以便在复制文件的一部分时调用它(它必须采用 PROGRESS_ROUTINE 格式,见下文)。
**lpData**:传递给回调函数的数据(可以为 NULL)。
**pbCancel**:如果在复制操作期间将此标志设置为 TRUE,则操作将被取消。
**dwCopyFlags**:指定文件复制的方式。可以是以下值的组合
COPY_FILE_FAIL_IF_EXISTS 如果 lpNewFileName 已存在,则复制操作失败
COPY_FILE_RESTARTABLE 复制进度在文件中跟踪。您可以使用 lpExistingFileName 和 lpNewFileName 的相同值稍后重新启动复制过程
复制进度例程的定义
DWORD WINAPI CopyProgressRoutine( LARGE_INTEGER TotalFileSize, // total file size of the file, in bytes LARGE_INTEGER TotalBytesTransferred, // total number of bytes transferred since operation started LARGE_INTEGER StreamSize, // size of current stream, in bytes LARGE_INTEGER StreamBytesTransferred, // total number of bytes transferred for this stream DWORD dwStreamNumber, // the current stream DWORD dwCallbackReason, // reason for callback HANDLE hSourceFile, // handle to the source file HANDLE hDestinationFile, // handle to the destination file LPVOID lpData // data passed by CopyFileEx );
您可以使用前四个参数来显示一个指示器,显示进程完成的百分比。
**dwCallbackReason**:可以具有以下值
CALLBACK_CHUNK_FINISHED 复制了数据的另一部分。
CALLBACK_STREAM_SWITCH 创建了一个流,并且它将被复制。这是 Copy Routine Callback 第一次被调用时的原因。
此函数必须返回以下值之一
**PROGRESS_CONTINUE** 继续复制
**PROGRESS_CANCEL** 取消复制操作并删除目标文件
**PROGRESS_STOP** 停止操作(它可以稍后重新启动)
**PROGRESS_QUIET** 继续复制操作,但不再调用 Copy Progress Routine
---
现在,让我们看看如何移动和重命名文件。我们需要使用的函数是 **MoveFile** 和 **MoveFileEx**。这些函数用于移动或重命名文件。当您调用其中一个函数时,系统只是将文件复制到新位置(如果您还重命名了它,则使用不同的名称)并删除旧文件。
BOOL MoveFileEx( LPCTSTR lpExistingFileName, // address of name of the existing file LPCTSTR lpNewFileName, // address of new name for the file DWORD dwFlags // flag to determine how to move file );
用于删除文件的 API 函数是 **DeleteFile** 。要删除的文件必须关闭,否则函数将失败。如果函数失败,则返回值为 0,如果成功,则为非零。
BOOL DeleteFile( LPCTSTR lpFileName // pointer to name of file to delete );
要删除目录,可以使用 **RemoveDirectory** 函数,但首先您必须删除其所有文件和子目录(它必须 **为空**)。
BOOL RemoveDirectory( LPCTSTR lpPathName // address of directory to remove );
**ReadDirectoryChangesW** 可用于监视目录(或卷)。它可以在目标目录中执行某些文件操作时传递通知。