磁盘文件的打开和关闭

时间:2022-03-12 10:02:17

       用了Qt或者linux之后··就觉得windows下的api很蛋疼-_-~

 

 

-----------

 

5.1 磁盘文件的打开和关闭

本节主要讲述磁盘文件的打开和创建,在最后讲述一些对目录的操作

在Win32下传统的ANSI C函数依然可以用来对函数进行操作,例如:fopen fread fwrite fclose,但M$推荐使用CreateFile,CreateFile函数的用途很多(我最开始时候被这个函数的多用途吓住了),可以打开和创建下面的设备文件:

  • Consoles
  • Communications resources
  • Directories (只能打开)
  • Files
  • Mailslots
  • Pipes

关于管道的创建和打开已经在上章4.5节讲过了,本章主要讲如何对磁盘文件的打开和创建操作。

HANDLE CreateFile(
  LPCTSTR lpFileName,                         // file name
  DWORD dwDesiredAccess,                      // access mode
  DWORD dwShareMode,                          // share mode
  LPSECURITY_ATTRIBUTES lpSecurityAttributes, // SD
  DWORD dwCreationDisposition,                // how to create
  DWORD dwFlagsAndAttributes,                 // file attributes
  HANDLE hTemplateFile                        // handle to template file
);

文件名 lpFileName:文件名的最大长度为MAX_PATH,文件可以为UNC,例如://server/file_name可以指明网络上其他主机上的文件。存取方法 dwDesiredAccess:可以通过指定参数表明打开文件读还是写,GENERIC_READ|GENERIC_WRITE表示一个文件进行读写。DELETE表示删除文件。共享属性 dwShareMode:表明文件打开后是否允许文件以某种存取方式(通过指定参数dwDesiredAccess的值)再次被打开,

  • 0 不允许文件再被打开
  • FILE_SHARE_DELETE 允许其他进程在以后打开文件进行删除
  • FILE_SHARE_READ 允许其他进程在以后打开文件进行读
  • FILE_SHARE_WRITE 允许其他进程在以后打开文件进行写

安全描述 lpSecurityAttributes:通过指定安全描述参数可以指定返回的句柄是否可以被子进程继承,如果设置为NULL则表明无法被继承。

typedef struct _SECURITY_ATTRIBUTES { 
  DWORD  nLength; 
  LPVOID lpSecurityDescriptor; 
  BOOL   bInheritHandle; 
} SECURITY_ATTRIBUTES, *PSECURITY_ATTRIBUTES;

在结构中设置nLength = sizeof(SECURITY_ATTRIBUTES),lpSecurityDescriptor = NULL,bInheritHandle = TRUE就可以使子进程能够集成句柄。

dwCreationDisposition用来设置文件在存在或不存在时系统采用的方法,可能的取值为:

  • CREATE_NEW:创建新文件,当文件已经存在时函数会返回失败
  • CREATE_ALWAYS:无论文件是否存在都创建新文件并且清楚原文件的所有属性
  • OPEN_EXISTING:打开存在的文件,当文件不存在时函数会返回失败
  • OPEN_ALWAYS:打开文件,当文件已经存在时函数会创建新文件
  • TRUNCATE_EXISTING:打开文件并将文件截断为零,当文件不存在时函数会返回失败

文件属性和参数 dwFlagsAndAttributes:通过这个参数来指定创建的文件属性和打开文件时的参数,文件属性可以是下面这些值的合并:

  • FILE_ATTRIBUTE_NORMAL 普通文件,设置这个属性时其他属性都不会生效
  • FILE_ATTRIBUTE_ARCHIVE 归档文件
  • FILE_ATTRIBUTE_HIDDEN 隐藏文件
  • FILE_ATTRIBUTE_READONLY 只读文件
  • FILE_ATTRIBUTE_SYSTEM 系统文件
  • FILE_ATTRIBUTE_TEMPORARY 临时文件 。

此外该参数还会指定文件操作的标记,可用的标记有下面这些:

  • FILE_FLAG_WRITE_THROUGH 使用WriteThrough模式,系统不会对文件使用缓存,文件的改变马上会被写入到磁盘
  • FILE_FLAG_OVERLAPPED 使用异步文件操作模式 Win9X不支持异步操作
  • FILE_FLAG_DELETE_ON_CLOSE 文件被关闭后立即删除文件
  • FILE_FLAG_RANDOM_ACCESS 说明对文件进行随机读写操作,用于暗示操作系统对该文件的缓存使用进行优化

文件模板 hTemplateFile:当指定文件模板的句柄时该文件模板的所有属性会被复制到当前创建的文件。

CreateFile和ANSI C函数中fopen的比较:

操作 fopen CreateFile
打开读 fopen("a.txt","r") CreateFile("a.txt",GENERIC_READ,0,NULL, 
OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL)
打开写并创建 fopen("a.txt","w") CreateFile("a.txt",GENERIC_WRITE,0,NULL, 
CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL)
打开读写 fopen("a.txt","r+") CreateFile("a.txt",GENERIC_WRITE|GENERIC_READ,0,NULL, 
OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL)
打开读写并创建 fopen("a.txt","w+") CreateFile("a.txt",GENERIC_WRITE|GENERIC_READ,0,NULL, 
CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL)

如果文件打开成功则返回文件句柄,否则返回INVALID_HANDLE_VALUE。通过GetLastError来获取错误信息。

文件的关闭很简单,只需要用CloseHandle就可以关闭文件,当文件被关闭时所有缓存内数据都会被写入到磁盘。

文件的删除可以使用下面的函数,并指明文件名

BOOL DeleteFile(
  LPCTSTR lpFileName   // file name
);

 

对于目录的创建可以使用:

BOOL CreateDirectory(
  LPCTSTR lpPathName,                         // directory name
  LPSECURITY_ATTRIBUTES lpSecurityAttributes  // 安全描述 通常情况下设置为NULL
);
BOOL CreateDirectoryEx(
  LPCTSTR lpTemplateDirectory,               // template directory
  LPCTSTR lpNewDirectory,                    // directory name
  LPSECURITY_ATTRIBUTES lpSecurityAttributes // SD
);

后一个函数可以创建一个和现有目录具有相同属性的新目录。

如果要删除一个存在的目录可以使用

BOOL RemoveDirectory(
  LPCTSTR lpPathName   // directory name
);

上面这些函数的返回值都是BOOL类型,可以通过返回值判断是否执行成功。如果失败可以通过GetLastError得到错误信息。