加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

C++和Win32API 文件操作

(2010-08-27 16:51:38)
标签:

杂谈

分类: C 和MFC

我们需要一个头文件 #include "fstream.h"

在C++,进行文件操作,写入数据,我们需要用到一个函数ofstream。

ofstream( const char* szName, int nMode = ios::out, int nProt = filebuf::openprot );

第一个参数,要打开的文件名,第二个参数打开的方式,有自己的参数列表:

  • ios::app  
  • ostream::seekp
  • ios::ate   
  • ios::in   
  • ios::out   
  • ios::trunc   
  • ios::nocreate   
  • ios::noreplace   
  • ios::binary   

第三个参数,文件保护的说明。也有自己的参数列表:

  • filebuf::sh_compat  
  • filebuf::sh_none  
  • filebuf::sh_read 
  • filebuf::sh_write

读取文件的时候我们用ifstream这个类:

ifstream( const char* szName, int nMode = ios::in, int nProt = filebuf::openprot );

 参数跟ofstream的参数类似,第二个参数有所区别。我们看一下第二个参数的参数列表:

  • ios::in
  • ios::nocreate
  • ios::binary 

我们看一下写入和读取的例子:

//写入

ofstream ofs("4.txt"); //构造一个对象
 ofs.write("woaicaiting",strlen("woaicaiting"));
 ofs.close();

//读取

ifstream ifs("4.txt");
 char ch[100];

//memset一般是用于初始化(清空)一个内存块,以防你新建一个变量等时系统分配给你一段含有用过的内存

//块。如果某君不小心不另外对其初始化就调用的话,可能会产生不可预料的错误。
 memset(ch,0,100);//作用是把字符数组当中的所有元素初始化为0。
 ifs.read(ch,100);
 ifs.close();
 MessageBox(ch);

 

我们看一下Win32API中对文件操作的几个函数:

首先我们看一下打开文件的函数:

HANDLE CreateFile(
  LPCTSTR
lpFileName         // pointer to name of the file
  DWORD dwDesiredAccess      // access (read-write) mode
  DWORD dwShareMode,           // share mode
  LPSECURITY_ATTRIBUTES lpSecurityAttributes,
                               // pointer to security attributes
  DWORD dwCreationDisposition // how to create
  DWORD dwFlagsAndAttributes // file attributes
  HANDLE hTemplateFile         // handle to file with attributes to
                               // copy
);
我们可以看到这个函数返回一个句柄。来表示打开或者创建对象的句柄

第一个参数,文件名

第二个参数,访问的方式,有两个参数:

GENERIC_READ

GENERIC_WRITE

第三个参数,共享方式:

指定文件对象如何被共享,参数如果为零,对象不能被共享 

第四个参数,指向SECURITY_ATTRIBUTES结构体的指针,用来确定返回的句柄,是否能被子进程所继承。用来指定我们所创建文件对象访问权限,以及返回对象的句柄是否能被子进程所继承。

我们看一下这个结构体

typedef struct _SECURITY_ATTRIBUTES { // sa
    DWORD  nLength;
    LPVOID lpSecurityDescriptor;
    BOOL   bInheritHandle;
} SECURITY_ATTRIBUTES

第四个参数设为NULL,创建的带有默认安全性的对象,返回的文件对象的句柄,是不能被继承的。

第五个参数,如何创建:有自己的参数

CREATE_NEW //创建一个新文件,如果文件存在,这个函数失败

CREATE_ALWAYS//创建一个文件,如果文件存在函数覆盖这个文件,清除现有属性

OPEN_EXISTING

OPEN_ALWAYS

TRUNCATE_EXISTING

第六个参数,文件属性。

FILE_ATTRIBUTE_ARCHIVE 
FILE_ATTRIBUTE_HIDDEN 
FILE_ATTRIBUTE_NORMAL 
FILE_ATTRIBUTE_OFFLINE 
FILE_ATTRIBUTE_READONLY 
FILE_ATTRIBUTE_SYSTEM 
FILE_ATTRIBUTE_TEMPORARY
FILE_FLAG_WRITE_THROUGH
FILE_FLAG_OVERLAPPED
FILE_FLAG_NO_BUFFERING
FILE_FLAG_RANDOM_ACCESS
FILE_FLAG_SEQUENTIAL_SCAN
FILE_FLAG_DELETE_ON_CLOSE
FILE_FLAG_BACKUP_SEMANTICS
FILE_FLAG_POSIX_SEMANTICS
FILE_FLAG_OPEN_REPARSE_POINT
FILE_FLAG_OPEN_NO_RECALL

为我们的文件设置文件属性和标记,可以去以上几个值。我们可以用最普通的一个值:FILE_ATTRIBUTE_NORMAL

 最后一个参数:是一个句柄,用来指定以GENERIC_READ这种方式打开的,模板文件的句柄。

作用,如果说我们传递了一个文件句柄,那么第六个参数的文件属性将被忽略,而是用GENERIC_READ所标识的文件的属性。

有了这些,我们新建一个句柄:

HANDLE hFile;

创建一个文件:

CreateFile("5.txt",GENERIC_WRITE,0,NULL,CREATE_NEW,FILE_ATTRIBUTE_NORMAL,NULL);

然后用到一个写入文件的函数:

BOOL WriteFile(
  HANDLE
hFile                   // handle to file to write to
  LPCVOID lpBuffer               // pointer to data to write to file
  DWORD nNumberOfBytesToWrite    // number of bytes to write
  LPDWORD lpNumberOfBytesWritten // pointer to number of bytes written
  LPOVERLAPPED lpOverlapped        // pointer to structure for overlapped I/O
);
第一个参数 文件的一个句柄,

第二个参数 是一个指针,指向一个buffer,将要写入文件的数据

第三个参数 将要写多少个字节

第四个参数 指向一个变量来接收实际写入到文件的字节数。

最后一个参数 指向 Overlapped结构体的指针。

最后一个参数想要起作用,在我们打开文件的时候,设置文件属性的时候,我们需要加上一个标记。

FILE_FLAG_OVERLAPPED设置这个标识,就是告诉系统,我们想要异步的去访问一个文件。如果没有设置这个标记

我们打开文件是同步IO的方式

我们要了解一下同步和异步。同步IO就是我们写入数据或者读取数据的时候,如果数据没有完整的写入到文件中,或者没有读完,程序将被挂起,知道写入完成,读取完成,程序才能继续运行。而我们设置了这个标记,异步IO方式告诉操作系统,读写数据不必等到IO结束,函数调用立即返回。返回了,但是读写操作没有完成怎么办呢,操作系统会使用线程我们完成这个IO。当操作系统完成了IO操作时,我们会得到通知。

我们再打开文件的时候并没有设置FILE_FLAG_OVERLAPPED.

所以我们调用WriteFile时,最后一个参数设置为NULL 。

HANDLE hFile;//定义一个句柄

//打开一个文件,获得文件的句柄,这里是创建一个文件
 hFile=CreateFile("5.txt",GENERIC_WRITE,0,NULL,CREATE_NEW,FILE_ATTRIBUTE_NORMAL,NULL);
 DWORD dwWrites; //定义一个变量来接收实际写入的字符数
 WriteFile(hFile,"lengquan",strlen("lengquan"),&dwWrites,NULL); //写入数据
 CloseHandle(hFile);//关闭文件 关闭句柄。

 

接下来是读取文件。

大部分跟写入相同,这里我们需要一个函数ReadFile来读取文件

BOOL ReadFile(
  HANDLE hFile,                // handle of file to read
  LPVOID lpBuffer,             // pointer to buffer that receives data
  DWORD nNumberOfBytesToRead,  // number of bytes to read
  LPDWORD lpNumberOfBytesRead, // pointer to number of bytes read
  LPOVERLAPPED lpOverlapped    // pointer to structure for data
);

 

 我们看一下一个例子:

HANDLE hFile;
 hFile=CreateFile("5.txt",GENERIC_READ,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
 char ch[100];
 DWORD dwReads;
 ReadFile(hFile,ch,100,&dwReads,NULL);
 ch[dwReads]=0;
 CloseHandle(hFile);
 MessageBox(ch);

 

 

 

 

0

阅读 收藏 喜欢 打印举报/Report
前一篇:MFC 文件操作
后一篇:MFC的文件操作
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有