createfile
文件内核对象
各种设备及其常见用途:
设备 | 常见用途 |
---|---|
文件 | 永久存储任何数据 |
目录 | 属性和文件压缩的设置 |
逻辑磁盘驱动器 | 格式化驱动器 |
物理磁盘驱动器 | 访问分区表 |
串口 | 通过电话线传输数据 |
并口 | 将数据传输至打印机 |
邮件槽 | 一对多数据传输,通常是通过网络传到另一台运行windows机器上 |
命名管道 | 一对一数据传输,通常是通过网络传到另一台运行Windows机器上 |
匿名管道 | 单机上的一对一数据传输(绝对不会跨网络) |
套接字 | 报文或数据流的传输,通常是通过网络传到任何支持套接字的机器上 |
控制台 | 文本窗口的屏幕缓存 |
用来打开各种设备的函数:
设备 | 用来打开设备的函数 |
---|---|
文件 | CreateFile(pszName 为路径名或UNC路径名) |
目录 | CreateFile(pszName为路径名或UNC路径名)。如果调用 CreateFile 的时候指定 FILE_FLAG_BACKUP_SEMANTICS标志,那么Windows允许我们打开一个目录。打开目录使我们能够改变目录的属性 |
逻辑磁盘驱动器 | CreateFile(pszName 为“\.\x:”)。如果指定的字符串是”\.\x:”的形式,那么Windows允许我们打开一个逻辑磁盘驱动器,其中的x是驱动器的盘符。打开驱动器使我们能够格式化驱动器或检测驱动器媒介的大小 |
物理磁盘驱动器 | CreateFile(pszName 为 “\\.\PHYSICALDRIVEx”)。如果指定的字符串是“\\.\PHYSICALDRIVEx”的形式,那么Windows允许我们打开一个物理磁盘驱动器,其中的x是物理驱动器号。例如,读写第一个物理磁盘驱动器的扇区——\\.\PHYSICALDRIVE0。打开物理驱动器使我们能直接访问磁盘分区表。打开物理驱动器有潜在的危险,错误地写入设备可能会导致操作系统的文件系统无法访问磁盘的内容 |
串口 | CreateFile(pszName 为”COMx”) |
并口 | CreateFile(pszName, 为”LPTx”) |
邮件槽服务器 | CreateMailslot(pszName, 为 “\\.\mailslot\mailslotname”) |
邮件槽客户端 | CreateFile(pszName 为”\\servername\mailslotname”) |
命名管道服务器 | CreateNamedPipe(pszName 为”\\.\pipe\pipename”) |
命名管道客户端 | CreateFile(pszName 为”\\servername\pipe\pipename”) |
匿名管道 | CreatePipe用来打开服务器和客户端 |
套接字 | socket, accept 或 acceptex |
控制台 | CreateconsoleScreenBuffer 或 GetStdhandle |
以上CreateFile函数都是返回对应设备的句柄,通过设备句柄我们可与对应的设备进行通信,也可以使用对应设备的特有API进行设置。
调用SetCommConfig设置串口的波特率:
BOOL SetCommConfig(
HANDLE hCommDev,
LPCOMMCONFIG pCC,
Dword dwSize);
邮件槽在等待读取数据时,可以调用SetMailslotInfo来设置一个超时值:
BOOL SetMailslotInfo(
HANDLE hMailslot,
dword dwReadTimeout);
获取文件类型GetFileType的返回值:
值 | 描述 |
---|---|
FILE_TYPE_UNKNOWN | 指定的文件为未知类型 |
FILE_TYPE_DISK | 指定的文件是一个磁盘文件 |
FILE_TYPE_CHAR | 指定的文件是一个字符文件,一般来说是一个并口设备或控制台 |
FILE_TYPE_PIPE | 指定的文件是一个命名管道或匿名管道 |
1.文件内核对象打开及操作
HANDLE CreateFile(
PCTSTR pszName, //文件设备名
DWORD dwDesiredAccess, //读取方式
DWORD dwShareMode, //共享模式
PSECURITY_ATTRIBUTES psa, //安全属性
DWORD dwCreationgDisposition, //
DWORD dwFlagsAndAttributes,
HANDLE hFileTemplate);
dwDesiredAccess
值 | 含义 |
---|---|
0 | 不希望从设备读取数据或向设备写入数据。如果只想改变设备的配置(如:修改文件的时间戳),可以传0 |
GENERIC_READ | 允许对设备进行只读访问 |
GENERIC_WRITE | 允许对设备进行只写访问,该选项并没有隐含 GENERIC_READ标志 |
dwShareMode
值 | 含义 |
---|---|
0 | 要求独占对设备的访问。如果设备已经打开,CreateFile 调用会失败;如果成功地打开了设备,后续的 CreateFile 调用会失败 |
FILE_SHARE_READ | 如果有其他对象要用该设备,我们要求它们不得修改设备的数据;如果设备已经以写入方式或独占方式打开,那么CreateFile调用会失败 |
FILE_SHARE_WRITE | 如果有其他内核对象要使用该设备,则要求它们不得读取设备的数据 |
FILE_SHARE_DELETE | 当对文件进行操作的时候,我们不关心文件是否被逻辑删除或移动。在Windows内部,系统会先将文件标记为待删除,然后当该文件所有已打开的句柄都被关闭的时候,再将其真正的删除 |
dwCreationgDisposition
值 | 含义 |
---|---|
CREATE_NEW | 告诉CreateFile创建一个新文件,如果同名文件已经存在,那么 CreateFile调用会失败 |
CREATE_ALWAYS | 告诉CreateFile无论同名是否存在都创建新文件,若文件存在,则覆盖 |
OPEN_EXISTING | 告诉CreateFile打开一个已有的文件或设备,如果文件或设备不存在,那么CreateFile调用会失败 |
OPEN_ALWAYS | 告诉CreateFile打开一个已有的文件,如果文件存在,那么CreateFile会直接打开文件,如果不存在,则会创建一个新文件 |
TRUNCATE_EXISTING | 告诉CreateFile打开一个已有的文件并将文件大小截断为0字节,如果文件不存在,那么CreateFile调用会失败 |
dwFlagsAndAttributes
- 该参数的用途:
- 允许我们设置一些标志来微调与设备之间的通信;
- 如果设备是一个文件,我们还能够设置文件的属性.
值 | 含义 |
---|---|
通信标志–缓存 | |
FILE_FLAG_NO_BUFFERING | 该标志表示在访问文件的时候不要使用任何数据缓存 |
FILE_FLAG_SEQUENTIAL_SCAN | 指定系统顺序地访问文件,系统从文件读取的数据量会超过我们的要求(减少硬盘访问),指定了FILE_FLAG_NO_BUFFERING标志,该标志不生效 |
FILE_FLAG_RANDOM_ACCESS | 该标志表示系统不要提前读取文件数据(指定FILE_FLAG_NO_BUFFERING,则该标志不生效) |
FILE_FLAG_WRITE_THROUGH | 禁止写入文件时,将数据缓存在内存中(减少数据丢失的可能性) |
通信标志–其他标志 | |
FILE_FLAG_DELETE_ON_CLOSE | 文件所有的句柄都被关闭后,删除该文件 |
FILE_FLAG_BACKUP_SEMANTICS | 用于备份和恢复软件。在打开或创建任何文件之前,为了确保视图打开文件或创建文件的进程具有所需的访问特权 |
FILE_FLAG_POSIX_SEMANTICS | 让CreateFile在创建文件或打开文件时,以区分大小写的方式来查找文件名 |
FILE_FLAG_OPEN_REPARSE_POINT | 告诉系统忽略文件的重解析属性(重解析属性允许一个文件系统过滤器对打开文件、读取文件、写入文件以及关闭文件这些行为进行修改) |
FILE_FLAG_OPEN_NO_RECALL | 该标志告诉系统不要将文件内容刚从脱机存储器(offline storage,比如磁带)恢复到联机存储器(即online storage, 如硬盘) |
FILE_FLAG_OVERLAPPED | 该标志告诉系统我们想以异步方式来访问设备 |
文件设置 | |
FILE_ATTRIBUTE_ARCHIVE | 应用程序用该标志来将文件标记为待备份或待删除。当CreateFile创建一个新文件时,会自动设置该标志 |
FILE_ATTRIBUTE_ENCRYPTED | 文件是经过加密的 |
FILE_ATTRIBUTE_hidden | 文件是隐藏的。它不会出现在通常的目录清单中 |
FILE_ATTRIBUTE_NORMAL | 文件没有其他属性。只有单独使用的时候,这个标志才有效 |
FILE_ATTRIBUTE_NOT_content_INDEXED | 内容索引服务(content indexing service)不会对文件进行索引 |
FILE_ATTRIBUTE_OFFLINE | 文件虽然存在,但文件内容已经被转移到脱机存储中 |
FILE_ATTRIBUTE_READONLY | 文件只读 |
FILE_ATTRIBUTE_SYSTEM | 文件是操作系统的一部分,专供操作系统使用 |
FILE_ATTRIBUTE_TEMPORARY | 文件数据只会使用一小段时间。为了将访问时间降至最低,会尽量将文件数据保存在内存中 |
2.使用文件设备
获得文件的大小
BOOL GetFileSizeEx( HANDLE hFile, // 文件句柄 Plarge_integer pliFileSize); //64位标识文件大小 typedef union _LARGE_INTEGER { struct { DWORD LowPart; //Low 32-bit unsigned value LONG HighPart; //High 32-bit signed value }; LONGLONG QuadPart; //Full 64-bit signed value } LARGE_INTEGER, *PLARGE_INTEGER;
设置文件指针
每调用一次CreateFile函数都会打开一个文件内核对象用于管理文件,每个内核对象内部都维护了一个文件指针,表示应该在哪里执行下一次同步读取或写入操作。
BOOL SetFilePointerEx( HANDLE hFile, LARGE_INTEGER lidistanceToMove, //指针移动的距离(多少字节) PLARGE_INTEGER pliNewFilePointer, //移动后返回的新指针 DWORD dwMoveMethod); //如何解释liDistanceToMove,即从哪个位置开始移动liDistanceToMove的距离(FILE_BEGIN, FILE_CURRENT, FILE_END)
- 注意事项:
- 将文件指针的值设为超过文件当前的大小是正当操作,除非在该位置向文件写入数据或调用 SetEndOfFile 才会改变文件大小;
- 如果SetFilePointerEx操作的文件是用FILE_FLAG_NO_BUFFERING标志打开的,那么文件指针只能被设置为扇区大小的整数倍;
- 注意事项:
设置文件尾
BOOL SetEndOfFile(HANDLE hFile);
SetEndOfFile函数会根据文件对象的文件指针当前所在的位置来截断文件的大小或增大文件的大小
HANDLE hFile = CreateFile(...); LARGE_INTEGER liDistanceToMove; liDistanceToMove.QuadPart = 1024; SetFilePointerEx(hFile, liDistanceToMove, NULL, FILE_BEGIN); SetEndOfFile(hFile); CloseHandle(hFile);
相关阅读
CreateFileMapping的MSDN翻译和使用心得 测试创建和打开文件映射的时候老是得到"句柄无效"的错误, 仔细看了MSDN以后才发觉是函数